From dfaacea951384853d6f1dab12f765edf46e56d8d Mon Sep 17 00:00:00 2001 From: MuhammadM1998 Date: Sat, 25 Jan 2025 18:25:14 +0200 Subject: [PATCH 01/14] refactor: remove manually declared tanstack options --- src/runtime/components/Table.vue | 49 -------------------------------- 1 file changed, 49 deletions(-) diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 3edf586cd0..745b422593 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -13,13 +13,6 @@ import type { SortingState, ExpandedState, VisibilityState, - GlobalFilterOptions, - ColumnFiltersOptions, - ColumnPinningOptions, - VisibilityOptions, - ExpandedOptions, - SortingOptions, - RowSelectionOptions, Updater, CellContext, HeaderContext @@ -68,41 +61,6 @@ export interface TableProps { loading?: boolean loadingColor?: TableVariants['loadingColor'] loadingAnimation?: TableVariants['loadingAnimation'] - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering) - */ - globalFilterOptions?: Omit, 'onGlobalFilterChange'> - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-filtering#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-filtering) - */ - columnFiltersOptions?: Omit, 'getFilteredRowModel' | 'onColumnFiltersChange'> - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-pinning#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-pinning) - */ - columnPinningOptions?: Omit - /** - * @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) - */ - visibilityOptions?: Omit - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/sorting#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/sorting) - */ - sortingOptions?: Omit, 'getSortedRowModel' | 'onSortingChange'> - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/expanding#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/expanding) - */ - expandedOptions?: Omit, 'getExpandedRowModel' | 'onExpandedChange'> - /** - * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-selection#table-options) - * @link [Guide](https://tanstack.com/table/v8/docs/guide/row-selection) - */ - rowSelectionOptions?: Omit, 'onRowSelectionChange'> class?: any ui?: Partial } @@ -152,21 +110,14 @@ const tableApi = useVueTable({ data, columns: columns.value, getCoreRowModel: getCoreRowModel(), - ...(props.globalFilterOptions || {}), onGlobalFilterChange: updaterOrValue => valueUpdater(updaterOrValue, globalFilterState), - ...(props.columnFiltersOptions || {}), getFilteredRowModel: getFilteredRowModel(), onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFiltersState), - ...(props.visibilityOptions || {}), onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibilityState), - ...(props.columnPinningOptions || {}), onColumnPinningChange: updaterOrValue => valueUpdater(updaterOrValue, columnPinningState), - ...(props.rowSelectionOptions || {}), onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelectionState), - ...(props.sortingOptions || {}), getSortedRowModel: getSortedRowModel(), onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sortingState), - ...(props.expandedOptions || {}), getExpandedRowModel: getExpandedRowModel(), onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expandedState), state: { From 93bca1fa1bb79a17abd44b11b9a33e17f0f4dd60 Mon Sep 17 00:00:00 2001 From: MuhammadM1998 Date: Sat, 25 Jan 2025 18:27:08 +0200 Subject: [PATCH 02/14] feat: add `tanstackOptions` prop and use defu to pass our defaults --- src/runtime/components/Table.vue | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 745b422593..85377a5930 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -15,7 +15,8 @@ import type { VisibilityState, Updater, CellContext, - HeaderContext + HeaderContext, + TableOptionsWithReactiveData } from '@tanstack/vue-table' import _appConfig from '#build/app.config' import theme from '#build/ui/table' @@ -39,6 +40,8 @@ type TableVariants = VariantProps export type TableColumn = ColumnDef +export type TableTanstackOptions = Omit, 'data' | 'columns' | 'getCoreRowModel'> + export interface TableData { [key: string]: any } @@ -51,6 +54,7 @@ export interface TableProps { as?: any data?: T[] columns?: TableColumn[] + tanstackOptions?: TableTanstackOptions caption?: string /** * Whether the table should have a sticky header. @@ -78,6 +82,7 @@ export type TableSlots = { + + diff --git a/docs/content/3.components/table.md b/docs/content/3.components/table.md index 82eb61ebf2..d692f40f47 100644 --- a/docs/content/3.components/table.md +++ b/docs/content/3.components/table.md @@ -404,6 +404,17 @@ class: '!p-0' --- :: +### With pagination +We already pass the `getPaginationRowModel` function to the table so you don't need to pass it again. There are different pagination approaches as explained in [Pagination Guide](https://tanstack.com/table/v8/docs/guide/pagination#pagination-guide). You can implement any of them by passing options to `tanstackOptions` prop. In the example below, we use the `initialState` prop to set the default page size and use `UPagination` component to control the pagination state. +::component-example +--- +prettier: true +collapse: true +name: 'table-pagination-example' +class: '!p-0' +--- +:: + ### With slots You can use slots to customize the header and data cells of the table. From 20307f4551fdca2ecbced5ab9108d1d752086345 Mon Sep 17 00:00:00 2001 From: Sandros94 Date: Sat, 1 Feb 2025 19:22:40 +0100 Subject: [PATCH 05/14] feat(Table): most tanstack options as top-level props --- src/runtime/components/Table.vue | 56 ++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index bf4fd833e6..4ecd00553b 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -16,7 +16,20 @@ import type { Updater, CellContext, HeaderContext, - TableOptionsWithReactiveData + CoreOptions, + VisibilityOptions, + ColumnOrderOptions, + ColumnPinningOptions, + RowPinningOptions, + FacetedOptions, + // ColumnFiltersOptions, + GlobalFilterOptions, + // SortingOptions, + // GroupingOptions, + ExpandedOptions, + ColumnSizingOptions, + PaginationOptions, + RowSelectionOptions } from '@tanstack/vue-table' import _appConfig from '#build/app.config' import theme from '#build/ui/table' @@ -38,15 +51,32 @@ const table = tv({ extend: tv(theme), ...(appConfigTable.ui?.table || {}) }) type TableVariants = VariantProps -export type TableColumn = ColumnDef - -export type TableTanstackOptions = Omit, 'data' | 'columns' | 'getCoreRowModel'> +export type TableData = RowData + +export type TableColumn = ColumnDef + +interface FeatureOptions extends VisibilityOptions, + ColumnOrderOptions, + ColumnPinningOptions, + RowPinningOptions, + FacetedOptions, + // ColumnFiltersOptions, + GlobalFilterOptions, + // SortingOptions, + // GroupingOptions, + ExpandedOptions, + ColumnSizingOptions, + PaginationOptions, + RowSelectionOptions { +} -export interface TableData { - [key: string]: any +export interface TableOptions extends Omit, 'state' | 'onStateChange' | 'renderFallbackValue'>, FeatureOptions { + state?: CoreOptions['state'] + onStateChange?: CoreOptions['onStateChange'] + renderFallbackValue?: CoreOptions['renderFallbackValue'] } -export interface TableProps { +export interface TableProps extends Omit, 'data' | 'columns' | 'getCoreRowModel'> { /** * The element or component this component should render as. * @defaultValue 'div' @@ -54,7 +84,6 @@ export interface TableProps { as?: any data?: T[] columns?: TableColumn[] - tanstackOptions?: TableTanstackOptions caption?: string /** * Whether the table should have a sticky header. @@ -84,7 +113,8 @@ export type TableSlots = { import { computed } from 'vue' import { defu } from 'defu' import { Primitive } from 'reka-ui' -import { FlexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getExpandedRowModel, getPaginationRowModel, useVueTable } from '@tanstack/vue-table' +import { FlexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getExpandedRowModel, useVueTable } from '@tanstack/vue-table' +import { reactiveOmit } from '@vueuse/core' import { upperFirst } from 'scule' import { useLocale } from '../composables/useLocale' @@ -110,12 +140,13 @@ const columnPinningState = defineModel('columnPinning', { de const rowSelectionState = defineModel('rowSelection', { default: {} }) const sortingState = defineModel('sorting', { default: [] }) const expandedState = defineModel('expanded', { default: {} }) +const tableProps = reactiveOmit(props, 'as', 'data', 'columns', 'caption', 'sticky', 'loading', 'loadingColor', 'loadingAnimation', 'class', 'ui') -const tableApi = useVueTable(defu(props.tanstackOptions, { +const tableApi = useVueTable(defu({ data, columns: columns.value, getCoreRowModel: getCoreRowModel(), - onGlobalFilterChange: (updaterOrValue: any) => valueUpdater(updaterOrValue, globalFilterState), + onGlobalFilterChange: (updaterOrValue: Updater) => valueUpdater(updaterOrValue, globalFilterState), getFilteredRowModel: getFilteredRowModel(), onColumnFiltersChange: (updaterOrValue: Updater) => valueUpdater(updaterOrValue, columnFiltersState), onColumnVisibilityChange: (updaterOrValue: Updater) => valueUpdater(updaterOrValue, columnVisibilityState), @@ -125,7 +156,6 @@ const tableApi = useVueTable(defu(props.tanstackOptions, { onSortingChange: (updaterOrValue: Updater) => valueUpdater(updaterOrValue, sortingState), getExpandedRowModel: getExpandedRowModel(), onExpandedChange: (updaterOrValue: Updater) => valueUpdater(updaterOrValue, expandedState), - getPaginationRowModel: getPaginationRowModel(), state: { get globalFilter() { return globalFilterState.value @@ -149,7 +179,7 @@ const tableApi = useVueTable(defu(props.tanstackOptions, { return sortingState.value } } -})) +}, tableProps)) function valueUpdater>(updaterOrValue: T, ref: Ref) { ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue From aaeef77f06cbf650b5afb0a8a111ab8b50d5a318 Mon Sep 17 00:00:00 2001 From: Sandros94 Date: Sat, 1 Feb 2025 21:53:18 +0100 Subject: [PATCH 06/14] fix(Table): select and visibility --- src/runtime/components/Table.vue | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 4ecd00553b..9dd18d5d85 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -17,7 +17,7 @@ import type { CellContext, HeaderContext, CoreOptions, - VisibilityOptions, + // VisibilityOptions, ColumnOrderOptions, ColumnPinningOptions, RowPinningOptions, @@ -28,8 +28,7 @@ import type { // GroupingOptions, ExpandedOptions, ColumnSizingOptions, - PaginationOptions, - RowSelectionOptions + PaginationOptions } from '@tanstack/vue-table' import _appConfig from '#build/app.config' import theme from '#build/ui/table' @@ -55,7 +54,8 @@ export type TableData = RowData export type TableColumn = ColumnDef -interface FeatureOptions extends VisibilityOptions, +interface FeatureOptions extends + // VisibilityOptions, ColumnOrderOptions, ColumnPinningOptions, RowPinningOptions, @@ -66,8 +66,7 @@ interface FeatureOptions extends VisibilityOptions, // GroupingOptions, ExpandedOptions, ColumnSizingOptions, - PaginationOptions, - RowSelectionOptions { + PaginationOptions { } export interface TableOptions extends Omit, 'state' | 'onStateChange' | 'renderFallbackValue'>, FeatureOptions { @@ -142,7 +141,7 @@ const sortingState = defineModel('sorting', { default: [] }) const expandedState = defineModel('expanded', { default: {} }) const tableProps = reactiveOmit(props, 'as', 'data', 'columns', 'caption', 'sticky', 'loading', 'loadingColor', 'loadingAnimation', 'class', 'ui') -const tableApi = useVueTable(defu({ +const tableApi = useVueTable(defu(tableProps, { data, columns: columns.value, getCoreRowModel: getCoreRowModel(), @@ -179,7 +178,7 @@ const tableApi = useVueTable(defu({ return sortingState.value } } -}, tableProps)) +})) function valueUpdater>(updaterOrValue: T, ref: Ref) { ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue From 8c9cb695c2771355adbc869925ec810c0201e4a0 Mon Sep 17 00:00:00 2001 From: Sandros94 Date: Sat, 1 Feb 2025 21:54:08 +0100 Subject: [PATCH 07/14] docs(Table): update pagination example --- .../examples/table/TablePaginationExample.vue | 12 ++++++++++-- docs/content/3.components/table.md | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/app/components/content/examples/table/TablePaginationExample.vue b/docs/app/components/content/examples/table/TablePaginationExample.vue index a4125a2a32..ef805e1c59 100644 --- a/docs/app/components/content/examples/table/TablePaginationExample.vue +++ b/docs/app/components/content/examples/table/TablePaginationExample.vue @@ -1,6 +1,9 @@ diff --git a/docs/app/components/content/examples/table/TablePaginationExample.vue b/docs/app/components/content/examples/table/TablePaginationExample.vue index ef805e1c59..50e8c8da63 100644 --- a/docs/app/components/content/examples/table/TablePaginationExample.vue +++ b/docs/app/components/content/examples/table/TablePaginationExample.vue @@ -160,11 +160,11 @@ const columns: TableColumn[] = [{ class="flex-1" /> diff --git a/docs/app/components/content/examples/table/TableRowSelectionExample.vue b/docs/app/components/content/examples/table/TableRowSelectionExample.vue index e242b02885..aa0e0ab7e5 100644 --- a/docs/app/components/content/examples/table/TableRowSelectionExample.vue +++ b/docs/app/components/content/examples/table/TableRowSelectionExample.vue @@ -114,8 +114,8 @@ const rowSelection = ref({ 1: true }) />
- {{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of - {{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected. + {{ table?.getFilteredSelectedRowModel().rows.length || 0 }} of + {{ table?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
diff --git a/docs/content/3.components/table.md b/docs/content/3.components/table.md index e242a60129..525ab237c1 100644 --- a/docs/content/3.components/table.md +++ b/docs/content/3.components/table.md @@ -456,11 +456,7 @@ const table = useTemplateRef('table') ``` -This will give you access to the following: - -| Name | Type | -| ---- | ---- | -| `tableApi`{lang="ts-type"} | [`Ref`{lang="ts-type"}](https://tanstack.com/table/latest/docs/api/core/table#table-api) | +This will give you access to the [TanStack Table API](https://tanstack.com/table/latest/docs/api/core/table#table-api). ## Theme diff --git a/playground/app/pages/components/table.vue b/playground/app/pages/components/table.vue index 8cdc3f3225..ede2407f36 100644 --- a/playground/app/pages/components/table.vue +++ b/playground/app/pages/components/table.vue @@ -2,6 +2,7 @@ import { h, resolveComponent } from 'vue' import { upperFirst } from 'scule' import type { TableColumn } from '@nuxt/ui' +import { getPaginationRowModel } from '@tanstack/vue-table' const UButton = resolveComponent('UButton') const UCheckbox = resolveComponent('UCheckbox') @@ -284,21 +285,21 @@ onMounted(() => {
column.getCanHide()).map(column => ({ label: upperFirst(column.id), type: 'checkbox' as const, checked: column.getIsVisible(), onUpdateChecked(checked: boolean) { - table?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked) + table?.getColumn(column.id)?.toggleVisibility(!!checked) }, onSelect(e?: Event) { e?.preventDefault() @@ -322,6 +323,7 @@ onMounted(() => { :columns="columns" :column-pinning="columnPinning" :loading="loading" + :get-pagination-row-model="getPaginationRowModel()" sticky :ui="{ tr: 'divide-x divide-[var(--ui-border)]' @@ -335,28 +337,28 @@ onMounted(() => {
- {{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of - {{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected. + {{ table?.getFilteredSelectedRowModel().rows.length || 0 }} of + {{ table?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
- +
diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 538cd96922..7a86de4b79 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -55,29 +55,29 @@ export type TableData = RowData export type TableColumn = ColumnDef -interface FeatureOptions extends +interface FeatureOptions extends /* @vue-ignore */ VisibilityOptions, ColumnOrderOptions, ColumnPinningOptions, - RowPinningOptions, - FacetedOptions, - /* @vue-ignore */ ColumnFiltersOptions, - GlobalFilterOptions, - /* @vue-ignore */ SortingOptions, + RowPinningOptions, + FacetedOptions, + /* @vue-ignore */ ColumnFiltersOptions, + GlobalFilterOptions, + /* @vue-ignore */ SortingOptions, /* @vue-ignore */ GroupingOptions, - ExpandedOptions, + ExpandedOptions, ColumnSizingOptions, PaginationOptions, - /* @vue-ignore */ RowSelectionOptions { + /* @vue-ignore */ RowSelectionOptions { } -export interface TableOptions extends Omit, 'state' | 'onStateChange' | 'renderFallbackValue'>, FeatureOptions { +export interface TableOptions extends Omit, 'data' | 'columns' | 'getCoreRowModel' | 'state' | 'onStateChange' | 'renderFallbackValue'>, FeatureOptions { state?: CoreOptions['state'] onStateChange?: CoreOptions['onStateChange'] renderFallbackValue?: CoreOptions['renderFallbackValue'] } -export interface TableProps extends Omit, 'data' | 'columns' | 'getCoreRowModel'> { +export interface TableProps extends TableOptions { /** * The element or component this component should render as. * @defaultValue 'div' @@ -141,6 +141,7 @@ const columnPinningState = defineModel('columnPinning', { de const rowSelectionState = defineModel('rowSelection', { default: {} }) const sortingState = defineModel('sorting', { default: [] }) const expandedState = defineModel('expanded', { default: {} }) + const tableProps = reactiveOmit(props, 'as', 'data', 'columns', 'caption', 'sticky', 'loading', 'loadingColor', 'loadingAnimation', 'class', 'ui') const tableApi = useVueTable(defu(tableProps, { @@ -186,9 +187,7 @@ function valueUpdater>(updaterOrValue: T, ref: Ref) { ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue } -defineExpose({ - tableApi -}) +defineExpose(tableApi) diff --git a/docs/app/components/content/examples/table/TablePaginationExample.vue b/docs/app/components/content/examples/table/TablePaginationExample.vue index 50e8c8da63..7b8e01889c 100644 --- a/docs/app/components/content/examples/table/TablePaginationExample.vue +++ b/docs/app/components/content/examples/table/TablePaginationExample.vue @@ -160,11 +160,11 @@ const columns: TableColumn[] = [{ class="flex-1" /> diff --git a/docs/app/components/content/examples/table/TableRowSelectionExample.vue b/docs/app/components/content/examples/table/TableRowSelectionExample.vue index aa0e0ab7e5..e242b02885 100644 --- a/docs/app/components/content/examples/table/TableRowSelectionExample.vue +++ b/docs/app/components/content/examples/table/TableRowSelectionExample.vue @@ -114,8 +114,8 @@ const rowSelection = ref({ 1: true }) />
- {{ table?.getFilteredSelectedRowModel().rows.length || 0 }} of - {{ table?.getFilteredRowModel().rows.length || 0 }} row(s) selected. + {{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of + {{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
diff --git a/playground/app/pages/components/table.vue b/playground/app/pages/components/table.vue index ede2407f36..461173a4f7 100644 --- a/playground/app/pages/components/table.vue +++ b/playground/app/pages/components/table.vue @@ -285,21 +285,21 @@ onMounted(() => {
column.getCanHide()).map(column => ({ label: upperFirst(column.id), type: 'checkbox' as const, checked: column.getIsVisible(), onUpdateChecked(checked: boolean) { - table?.getColumn(column.id)?.toggleVisibility(!!checked) + table?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked) }, onSelect(e?: Event) { e?.preventDefault() @@ -337,24 +337,24 @@ onMounted(() => {
- {{ table?.getFilteredSelectedRowModel().rows.length || 0 }} of - {{ table?.getFilteredRowModel().rows.length || 0 }} row(s) selected. + {{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of + {{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
Prev Next diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 7a86de4b79..7af21ef2e5 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -187,7 +187,9 @@ function valueUpdater>(updaterOrValue: T, ref: Ref) { ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue } -defineExpose(tableApi) +defineExpose({ + tableApi +}) ``` -This will give you access to the [TanStack Table API](https://tanstack.com/table/latest/docs/api/core/table#table-api). +This will give you access to the following: + +| Name | Type | +| ---- | ---- | +| `tableApi`{lang="ts-type"} | [`Ref
`{lang="ts-type"}](https://tanstack.com/table/latest/docs/api/core/table#table-api) | ## Theme From c191588e58df3928f360a8844c4de12eeefa0218 Mon Sep 17 00:00:00 2001 From: Sandros94 Date: Wed, 5 Feb 2025 17:46:24 +0100 Subject: [PATCH 12/14] feat(Talbe): `CoreOptions` as top-level props, plugins as dedicated ones --- .../examples/table/TablePaginationExample.vue | 4 +- playground/app/pages/components/table.vue | 2 - src/runtime/components/Table.vue | 126 +++++++++++++----- 3 files changed, 97 insertions(+), 35 deletions(-) diff --git a/docs/app/components/content/examples/table/TablePaginationExample.vue b/docs/app/components/content/examples/table/TablePaginationExample.vue index 7b8e01889c..8be4a761f3 100644 --- a/docs/app/components/content/examples/table/TablePaginationExample.vue +++ b/docs/app/components/content/examples/table/TablePaginationExample.vue @@ -150,7 +150,9 @@ const columns: TableColumn[] = [{ ref="table" :data="data" :columns="columns" - :get-pagination-row-model="getPaginationRowModel()" + :pagination-options="{ + getPaginationRowModel: getPaginationRowModel() + }" :initial-state="{ pagination: { pageIndex: 0, diff --git a/playground/app/pages/components/table.vue b/playground/app/pages/components/table.vue index 461173a4f7..36746595ca 100644 --- a/playground/app/pages/components/table.vue +++ b/playground/app/pages/components/table.vue @@ -2,7 +2,6 @@ import { h, resolveComponent } from 'vue' import { upperFirst } from 'scule' import type { TableColumn } from '@nuxt/ui' -import { getPaginationRowModel } from '@tanstack/vue-table' const UButton = resolveComponent('UButton') const UCheckbox = resolveComponent('UCheckbox') @@ -323,7 +322,6 @@ onMounted(() => { :columns="columns" :column-pinning="columnPinning" :loading="loading" - :get-pagination-row-model="getPaginationRowModel()" sticky :ui="{ tr: 'divide-x divide-[var(--ui-border)]' diff --git a/src/runtime/components/Table.vue b/src/runtime/components/Table.vue index 7af21ef2e5..ee3646a858 100644 --- a/src/runtime/components/Table.vue +++ b/src/runtime/components/Table.vue @@ -8,9 +8,14 @@ import type { Row, ColumnDef, ColumnFiltersState, + ColumnOrderState, ColumnPinningState, + ColumnSizingState, + ColumnSizingInfoState, RowSelectionState, + RowPinningState, SortingState, + GroupingState, ExpandedState, VisibilityState, Updater, @@ -18,14 +23,13 @@ import type { HeaderContext, CoreOptions, VisibilityOptions, - ColumnOrderOptions, ColumnPinningOptions, RowPinningOptions, FacetedOptions, ColumnFiltersOptions, GlobalFilterOptions, - SortingOptions, GroupingOptions, + SortingOptions, ExpandedOptions, ColumnSizingOptions, PaginationOptions, @@ -55,23 +59,7 @@ export type TableData = RowData export type TableColumn = ColumnDef -interface FeatureOptions extends - /* @vue-ignore */ VisibilityOptions, - ColumnOrderOptions, - ColumnPinningOptions, - RowPinningOptions, - FacetedOptions, - /* @vue-ignore */ ColumnFiltersOptions, - GlobalFilterOptions, - /* @vue-ignore */ SortingOptions, - /* @vue-ignore */ GroupingOptions, - ExpandedOptions, - ColumnSizingOptions, - PaginationOptions, - /* @vue-ignore */ RowSelectionOptions { -} - -export interface TableOptions extends Omit, 'data' | 'columns' | 'getCoreRowModel' | 'state' | 'onStateChange' | 'renderFallbackValue'>, FeatureOptions { +export interface TableOptions extends Omit, 'data' | 'columns' | 'getCoreRowModel' | 'state' | 'onStateChange' | 'renderFallbackValue'> { state?: CoreOptions['state'] onStateChange?: CoreOptions['onStateChange'] renderFallbackValue?: CoreOptions['renderFallbackValue'] @@ -95,6 +83,62 @@ export interface TableProps extends TableOptions { loading?: boolean loadingColor?: TableVariants['loadingColor'] loadingAnimation?: TableVariants['loadingAnimation'] + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering) + */ + globalFilterOptions?: Omit, 'onGlobalFilterChange'> + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-filtering#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-filtering) + */ + columnFiltersOptions?: Omit, 'getFilteredRowModel' | 'onColumnFiltersChange'> + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-pinning#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-pinning) + */ + columnPinningOptions?: Omit + /** + * @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 + /** + * @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) + */ + visibilityOptions?: Omit + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/sorting#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/sorting) + */ + sortingOptions?: Omit, '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 + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/expanding#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/expanding) + */ + expandedOptions?: Omit, 'getExpandedRowModel' | 'onExpandedChange'> + /** + * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-selection#table-options) + * @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/row-pinning#table-options) + * @link [Guide](https://tanstack.com/table/v8/docs/guide/row-pinning) + */ + rowPinningOptions?: Omit, '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?: PaginationOptions + facetedOptions?: FacetedOptions class?: any ui?: Partial } @@ -112,10 +156,8 @@ export type TableSlots = { diff --git a/docs/app/components/content/examples/table/TablePaginationExample.vue b/docs/app/components/content/examples/table/TablePaginationExample.vue index 8be4a761f3..a8b4926988 100644 --- a/docs/app/components/content/examples/table/TablePaginationExample.vue +++ b/docs/app/components/content/examples/table/TablePaginationExample.vue @@ -142,31 +142,33 @@ const columns: TableColumn[] = [{ return h('div', { class: 'text-right font-medium' }, formatted) } }] + +const pagination = ref({ + pageIndex: 0, + pageSize: 5 +}) diff --git a/docs/content/3.components/table.md b/docs/content/3.components/table.md index e242a60129..5615f636c3 100644 --- a/docs/content/3.components/table.md +++ b/docs/content/3.components/table.md @@ -336,7 +336,7 @@ You can use the `column-pinning` prop to control the pinning state of the column ### With column visibility -You can add use [DropdownMenu](/components/dropdown-menu) component to toggle the visibility of the columns using the TanStack Table [Column Visibility APIs](https://tanstack.com/table/latest/docs/api/features/column-visibility). +You can use a [DropdownMenu](/components/dropdown-menu) component to toggle the visibility of the columns using the TanStack Table [Column Visibility APIs](https://tanstack.com/table/latest/docs/api/features/column-visibility). ::component-example --- @@ -391,26 +391,34 @@ class: '!p-0' You can use the `global-filter` prop to control the global filter state (can be binded with `v-model`). :: -### With fetched data +### With pagination -You can fetch data from an API and use them in the Table. +You can use a [Pagination](/components/pagination) component to control the pagination state using the [Pagination APIs](https://tanstack.com/table/latest/docs/api/features/pagination). + +There are different pagination approaches as explained in [Pagination Guide](https://tanstack.com/table/latest/docs/guide/pagination#pagination-guide). In this example, we use client-side pagination so we need to manually pass `getPaginationRowModel()`{lang="ts-type"} function. ::component-example --- prettier: true collapse: true -name: 'table-fetch-example' +name: 'table-pagination-example' class: '!p-0' --- :: -### With pagination -There are different pagination approaches as explained in [Pagination Guide](https://tanstack.com/table/v8/docs/guide/pagination#pagination-guide). In the example below, we use the `initialState` prop to set the default page index and size and use `UPagination` component to control the pagination state. To support client side navigation you need to manually pass `getPaginationRowModel` function. +::tip +You can use the `pagination` prop to control the pagination state (can be binded with `v-model`). +:: + +### With fetched data + +You can fetch data from an API and use them in the Table. + ::component-example --- prettier: true collapse: true -name: 'table-pagination-example' +name: 'table-fetch-example' class: '!p-0' --- :: diff --git a/playground/app/pages/components/table.vue b/playground/app/pages/components/table.vue index 36746595ca..d87a92fe01 100644 --- a/playground/app/pages/components/table.vue +++ b/playground/app/pages/components/table.vue @@ -2,6 +2,7 @@ import { h, resolveComponent } from 'vue' import { upperFirst } from 'scule' import type { TableColumn } from '@nuxt/ui' +import { getPaginationRowModel } from '@tanstack/vue-table' const UButton = resolveComponent('UButton') const UCheckbox = resolveComponent('UCheckbox') @@ -323,10 +324,13 @@ onMounted(() => { :column-pinning="columnPinning" :loading="loading" sticky + :pagination-options="{ + getPaginationRowModel: getPaginationRowModel() + }" :ui="{ tr: 'divide-x divide-[var(--ui-border)]' }" - class="border border-[var(--ui-border-accented)] rounded-[var(--ui-radius)] flex-1" + class="border border-[var(--ui-border-accented)] rounded-[var(--ui-radius)]" >