diff --git a/playground/app/pages/components/table.vue b/playground/app/pages/components/table.vue index cc3b866dd0..16aee0ae92 100644 --- a/playground/app/pages/components/table.vue +++ b/playground/app/pages/components/table.vue @@ -264,6 +264,12 @@ const columnPinning = ref({ right: ['actions'] }) +const page = ref(1) + +watch(page, () => { + tableApi.setPageIndex(page.value - 1) +}) + function randomize() { data.value = [...data.value].sort(() => Math.random() - 0.5) } @@ -317,6 +323,7 @@ onMounted(() => { :columns="columns" :column-pinning="columnPinning" :loading="loading" + :pagination="{ pageSize: 10, pageIndex: 0 }" sticky class="border border-[var(--ui-border-accented)] rounded-[var(--ui-radius)] flex-1" > @@ -324,6 +331,7 @@ onMounted(() => {
{{ row.original }}
+
diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 67ba35efc1..97b52fedd2 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -19,9 +19,11 @@ import type { ExpandedOptions, SortingOptions, RowSelectionOptions, + PaginationOptions, Updater, CellContext, - HeaderContext + HeaderContext, + PaginationState } from '@tanstack/vue-table' import _appConfig from '#build/app.config' import theme from '#build/ui/table' @@ -86,6 +88,11 @@ export interface TableProps { * @link [Guide](https://tanstack.com/table/v8/docs/guide/row-selection) */ rowSelectionOptions?: Omit, 'onRowSelectionChange'> + /** + * @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 class?: any ui?: Partial } @@ -97,6 +104,7 @@ export type TableSlots = { expanded: (props: { row: Row }) => any empty: (props?: {}) => any caption: (props?: {}) => any + pagination: (props?: {}) => any } & DynamicHeaderSlots & DynamicCellSlots @@ -109,7 +117,8 @@ import { getFilteredRowModel, getSortedRowModel, getExpandedRowModel, - useVueTable + useVueTable, + getPaginationRowModel } from '@tanstack/vue-table' import { upperFirst } from 'scule' import { useLocale } from '../composables/useLocale' @@ -128,6 +137,15 @@ const ui = computed(() => table({ loadingAnimation: props.loadingAnimation })) +// workaround to disable pagination when no pagination options are provided because passing +// getPaginationRowModel to useVueTable will automatically enable pagination +const paginationStateOverride = computed(() => !paginationState.value && !props.paginationOptions + ? { + pageSize: data.value.length, + pageIndex: 0 + } + : paginationState.value) + const globalFilterState = defineModel('globalFilter', { default: undefined }) const columnFiltersState = defineModel('columnFilters', { default: [] }) const columnVisibilityState = defineModel('columnVisibility', { default: {} }) @@ -135,6 +153,7 @@ const columnPinningState = defineModel('columnPinning', { de const rowSelectionState = defineModel('rowSelection', { default: {} }) const sortingState = defineModel('sorting', { default: [] }) const expandedState = defineModel('expanded', { default: {} }) +const paginationState = defineModel('pagination', { default: undefined }) const tableApi = useVueTable({ data, @@ -157,6 +176,9 @@ const tableApi = useVueTable({ ...(props.expandedOptions || {}), getExpandedRowModel: getExpandedRowModel(), onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expandedState), + getPaginationRowModel: getPaginationRowModel(), + ...(props.paginationOptions || {}), + onPaginationChange: updaterOrValue => valueUpdater(updaterOrValue, paginationState), state: { get globalFilter() { return globalFilterState.value @@ -178,6 +200,9 @@ const tableApi = useVueTable({ }, get sorting() { return sortingState.value + }, + get pagination() { + return paginationStateOverride.value } } })