feat(Table): extends core options and support other options like pagination (#3177)

Co-authored-by: Sandros94 <sandro.circi@digitoolmedia.com>
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Muhammad Mahmoud
2025-02-05 23:04:00 +02:00
committed by GitHub
parent c5bb540519
commit 4aa317944e
5 changed files with 312 additions and 31 deletions

View File

@@ -3,26 +3,38 @@
import type { Ref } from 'vue'
import type { VariantProps } from 'tailwind-variants'
import type { AppConfig } from '@nuxt/schema'
import type { RowData } from '@tanstack/table-core'
import type {
Row,
ColumnDef,
ColumnFiltersState,
ColumnPinningState,
RowSelectionState,
SortingState,
ExpandedState,
VisibilityState,
GlobalFilterOptions,
ColumnFiltersOptions,
ColumnPinningOptions,
VisibilityOptions,
ExpandedOptions,
SortingOptions,
RowSelectionOptions,
Updater,
CellContext,
HeaderContext
ColumnDef,
ColumnFiltersOptions,
ColumnFiltersState,
ColumnOrderState,
ColumnPinningOptions,
ColumnPinningState,
ColumnSizingInfoState,
ColumnSizingOptions,
ColumnSizingState,
CoreOptions,
ExpandedOptions,
ExpandedState,
FacetedOptions,
GlobalFilterOptions,
GroupingOptions,
GroupingState,
HeaderContext,
PaginationOptions,
PaginationState,
Row,
RowData,
RowPinningOptions,
RowPinningState,
RowSelectionOptions,
RowSelectionState,
SortingOptions,
SortingState,
Updater,
VisibilityOptions,
VisibilityState
} from '@tanstack/vue-table'
import _appConfig from '#build/app.config'
import theme from '#build/ui/table'
@@ -44,13 +56,17 @@ const table = tv({ extend: tv(theme), ...(appConfigTable.ui?.table || {}) })
type TableVariants = VariantProps<typeof table>
export type TableColumn<T> = ColumnDef<T>
export type TableData = RowData
export interface TableData {
[key: string]: any
export type TableColumn<T extends TableData, D = unknown> = ColumnDef<T, D>
export interface TableOptions<T extends TableData> extends Omit<CoreOptions<T>, 'data' | 'columns' | 'getCoreRowModel' | 'state' | 'onStateChange' | 'renderFallbackValue'> {
state?: CoreOptions<T>['state']
onStateChange?: CoreOptions<T>['onStateChange']
renderFallbackValue?: CoreOptions<T>['renderFallbackValue']
}
export interface TableProps<T> {
export interface TableProps<T extends TableData> extends TableOptions<T> {
/**
* The element or component this component should render as.
* @defaultValue 'div'
@@ -83,6 +99,11 @@ export interface TableProps<T> {
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-pinning)
*/
columnPinningOptions?: Omit<ColumnPinningOptions, 'onColumnPinningChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-sizing#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-sizing)
*/
columnSizingOptions?: Omit<ColumnSizingOptions, 'onColumnSizingChange' | 'onColumnSizingInfoChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-visibility#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-visibility)
@@ -93,6 +114,11 @@ export interface TableProps<T> {
* @link [Guide](https://tanstack.com/table/v8/docs/guide/sorting)
*/
sortingOptions?: Omit<SortingOptions<T>, 'getSortedRowModel' | 'onSortingChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/grouping#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/grouping)
*/
groupingOptions?: Omit<GroupingOptions, 'onGroupingChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/expanding#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/expanding)
@@ -103,6 +129,21 @@ export interface TableProps<T> {
* @link [Guide](https://tanstack.com/table/v8/docs/guide/row-selection)
*/
rowSelectionOptions?: Omit<RowSelectionOptions<T>, 'onRowSelectionChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-pinning#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/row-pinning)
*/
rowPinningOptions?: Omit<RowPinningOptions<T>, 'onRowPinningChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/pagination#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/pagination)
*/
paginationOptions?: Omit<PaginationOptions, 'onPaginationChange'>
/**
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-faceting#table-options)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-faceting)
*/
facetedOptions?: FacetedOptions<T>
class?: any
ui?: Partial<typeof table.slots>
}
@@ -120,9 +161,10 @@ export type TableSlots<T> = {
<script setup lang="ts" generic="T extends TableData">
import { computed } from 'vue'
import { Primitive } from 'reka-ui'
import { FlexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getExpandedRowModel, useVueTable } from '@tanstack/vue-table'
import { Primitive, useForwardProps } from 'reka-ui'
import { upperFirst } from 'scule'
import { FlexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getExpandedRowModel, useVueTable } from '@tanstack/vue-table'
import { reactiveOmit } from '@vueuse/core'
import { useLocale } from '../composables/useLocale'
const props = defineProps<TableProps<T>>()
@@ -142,13 +184,22 @@ const ui = computed(() => table({
const globalFilterState = defineModel<string>('globalFilter', { default: undefined })
const columnFiltersState = defineModel<ColumnFiltersState>('columnFilters', { default: [] })
const columnOrderState = defineModel<ColumnOrderState>('columnOrder', { default: [] })
const columnVisibilityState = defineModel<VisibilityState>('columnVisibility', { default: {} })
const columnPinningState = defineModel<ColumnPinningState>('columnPinning', { default: {} })
const columnSizingState = defineModel<ColumnSizingState>('columnSizing', { default: {} })
const columnSizingInfoState = defineModel<ColumnSizingInfoState>('columnSizingInfo', { default: {} })
const rowSelectionState = defineModel<RowSelectionState>('rowSelection', { default: {} })
const rowPinningState = defineModel<RowPinningState>('rowPinning', { default: {} })
const sortingState = defineModel<SortingState>('sorting', { default: [] })
const groupingState = defineModel<GroupingState>('grouping', { default: [] })
const expandedState = defineModel<ExpandedState>('expanded', { default: {} })
const paginationState = defineModel<PaginationState>('pagination', { default: {} })
const tableProps = useForwardProps(reactiveOmit(props, 'as', 'data', 'columns', 'caption', 'sticky', 'loading', 'loadingColor', 'loadingAnimation', 'class', 'ui'))
const tableApi = useVueTable({
...tableProps,
data,
columns: columns.value,
getCoreRowModel: getCoreRowModel(),
@@ -157,18 +208,29 @@ const tableApi = useVueTable({
...(props.columnFiltersOptions || {}),
getFilteredRowModel: getFilteredRowModel(),
onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFiltersState),
onColumnOrderChange: updaterOrValue => valueUpdater(updaterOrValue, columnOrderState),
...(props.visibilityOptions || {}),
onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibilityState),
...(props.columnPinningOptions || {}),
onColumnPinningChange: updaterOrValue => valueUpdater(updaterOrValue, columnPinningState),
...(props.columnSizingOptions || {}),
onColumnSizingChange: updaterOrValue => valueUpdater(updaterOrValue, columnSizingState),
onColumnSizingInfoChange: updaterOrValue => valueUpdater(updaterOrValue, columnSizingInfoState),
...(props.rowSelectionOptions || {}),
onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelectionState),
...(props.rowPinningOptions || {}),
onRowPinningChange: updaterOrValue => valueUpdater(updaterOrValue, rowPinningState),
...(props.sortingOptions || {}),
getSortedRowModel: getSortedRowModel(),
onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sortingState),
...(props.groupingOptions || {}),
onGroupingChange: updaterOrValue => valueUpdater(updaterOrValue, groupingState),
...(props.expandedOptions || {}),
getExpandedRowModel: getExpandedRowModel(),
onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expandedState),
...(props.paginationOptions || {}),
onPaginationChange: updaterOrValue => valueUpdater(updaterOrValue, paginationState),
...(props.facetedOptions || {}),
state: {
get globalFilter() {
return globalFilterState.value
@@ -176,6 +238,9 @@ const tableApi = useVueTable({
get columnFilters() {
return columnFiltersState.value
},
get columnOrder() {
return columnOrderState.value
},
get columnVisibility() {
return columnVisibilityState.value
},
@@ -190,6 +255,21 @@ const tableApi = useVueTable({
},
get sorting() {
return sortingState.value
},
get grouping() {
return groupingState.value
},
get rowPinning() {
return rowPinningState.value
},
get columnSizing() {
return columnSizingState.value
},
get columnSizingInfo() {
return columnSizingInfoState.value
},
get pagination() {
return paginationState.value
}
}
})