Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { functionalUpdate } from '../../utils'
import { functionalUpdate, shallowEqual } from '../../utils'
import type { RowData, Updater } from '../../types/type-utils'
import type { TableFeatures } from '../../types/TableFeatures'
import type { Table_Internal } from '../../types/Table'
Expand Down Expand Up @@ -37,6 +37,14 @@ export function table_setPagination<
return newState
}

const currentPagination = table.store.state.pagination
if (currentPagination) {
const newPagination = functionalUpdate(safeUpdater, currentPagination)
if (shallowEqual(currentPagination, newPagination)) {
return
}
}

return table.options.onPaginationChange?.(safeUpdater)
}

Expand Down
19 changes: 19 additions & 0 deletions packages/table-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ export function functionalUpdate<T>(updater: Updater<T>, input: T): T {
: updater
}

export function shallowEqual<T>(a: T, b: T): boolean {
if (Object.is(a, b)) return true
if (
typeof a !== 'object' ||
typeof b !== 'object' ||
a === null ||
b === null
) {
return false
}
const keysA = Object.keys(a)
const keysB = Object.keys(b)
if (keysA.length !== keysB.length) return false
for (const key of keysA) {
if (!Object.is((a as any)[key], (b as any)[key])) return false
}
return true
}

export function noop() {}

export function makeStateUpdater<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { describe, expect, it, vi } from 'vitest'
import {
getDefaultPaginationState,
rowPaginationFeature,
table_autoResetPageIndex,
table_resetPageIndex,
table_setPageIndex,
table_setPagination,
} from '../../../../src'
import { generateTestTableWithData } from '../../../helpers/generateTestTable'

type TestFeatures = {
rowPaginationFeature: {}
}

function createPaginationTable(onPaginationChange?: (...args: any[]) => void) {
const table = generateTestTableWithData<TestFeatures>(10, {
_features: {
rowPaginationFeature,
},
...(onPaginationChange && { onPaginationChange }),
} as any)
return table
}

describe('rowPaginationFeature.utils', () => {
describe('getDefaultPaginationState', () => {
it('should return default pagination state', () => {
const state = getDefaultPaginationState()
expect(state).toEqual({ pageIndex: 0, pageSize: 10 })
})
})

describe('table_setPagination', () => {
it('should call onPaginationChange when state actually changes', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

table_setPagination(table as any, { pageIndex: 2, pageSize: 10 })

expect(onPaginationChange).toHaveBeenCalledTimes(1)
})

it('should NOT call onPaginationChange when state is unchanged (object updater)', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

// Set same values as default (pageIndex: 0, pageSize: 10)
table_setPagination(table as any, { pageIndex: 0, pageSize: 10 })

expect(onPaginationChange).not.toHaveBeenCalled()
})

it('should NOT call onPaginationChange when function updater returns same state', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

table_setPagination(table as any, (old) => ({ ...old }))

expect(onPaginationChange).not.toHaveBeenCalled()
})

it('should call onPaginationChange when function updater changes pageIndex', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

table_setPagination(table as any, (old) => ({
...old,
pageIndex: old.pageIndex + 1,
}))

expect(onPaginationChange).toHaveBeenCalledTimes(1)
})
})

describe('table_setPageIndex', () => {
it('should NOT trigger onPaginationChange when pageIndex is already at target', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

// Default pageIndex is 0, setting to 0 should be a no-op
table_setPageIndex(table as any, 0)

expect(onPaginationChange).not.toHaveBeenCalled()
})

it('should trigger onPaginationChange when pageIndex changes', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

table_setPageIndex(table as any, 1)

expect(onPaginationChange).toHaveBeenCalledTimes(1)
})
})

describe('table_resetPageIndex', () => {
it('should NOT trigger onPaginationChange when already at default', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

// Already at default pageIndex (0), reset should be a no-op
table_resetPageIndex(table as any, true)

expect(onPaginationChange).not.toHaveBeenCalled()
})
})

describe('table_autoResetPageIndex', () => {
it('should NOT trigger onPaginationChange when page index is already at default', () => {
const onPaginationChange = vi.fn()
const table = createPaginationTable(onPaginationChange)

// autoResetPageIndex resets to initial/default, which is already 0
table_autoResetPageIndex(table as any)

expect(onPaginationChange).not.toHaveBeenCalled()
})
})
})
Loading