mirror of
https://github.com/gosticks/react-table.git
synced 2026-02-28 03:22:44 +00:00
186 lines
3.9 KiB
JavaScript
Executable File
186 lines
3.9 KiB
JavaScript
Executable File
import React from 'react'
|
|
|
|
//
|
|
|
|
import {
|
|
actions,
|
|
ensurePluginOrder,
|
|
functionalUpdate,
|
|
useMountedLayoutEffect,
|
|
useGetLatest,
|
|
} from '../publicUtils'
|
|
|
|
import { expandRows } from '../utils'
|
|
|
|
const pluginName = 'usePagination'
|
|
|
|
// Actions
|
|
actions.resetPage = 'resetPage'
|
|
actions.gotoPage = 'gotoPage'
|
|
actions.setPageSize = 'setPageSize'
|
|
|
|
export const usePagination = hooks => {
|
|
hooks.stateReducers.push(reducer)
|
|
hooks.useInstance.push(useInstance)
|
|
}
|
|
|
|
usePagination.pluginName = pluginName
|
|
|
|
function reducer(state, action, previousState, instance) {
|
|
if (action.type === actions.init) {
|
|
return {
|
|
pageSize: 10,
|
|
pageIndex: 0,
|
|
...state,
|
|
}
|
|
}
|
|
|
|
if (action.type === actions.resetPage) {
|
|
return {
|
|
...state,
|
|
pageIndex: instance.initialState.pageIndex || 0,
|
|
}
|
|
}
|
|
|
|
if (action.type === actions.gotoPage) {
|
|
const { pageCount } = instance
|
|
const newPageIndex = functionalUpdate(action.pageIndex, state.pageIndex)
|
|
|
|
if (newPageIndex < 0 || newPageIndex > pageCount - 1) {
|
|
return state
|
|
}
|
|
return {
|
|
...state,
|
|
pageIndex: newPageIndex,
|
|
}
|
|
}
|
|
|
|
if (action.type === actions.setPageSize) {
|
|
const { pageSize } = action
|
|
const topRowIndex = state.pageSize * state.pageIndex
|
|
const pageIndex = Math.floor(topRowIndex / pageSize)
|
|
|
|
return {
|
|
...state,
|
|
pageIndex,
|
|
pageSize,
|
|
}
|
|
}
|
|
}
|
|
|
|
function useInstance(instance) {
|
|
const {
|
|
rows,
|
|
autoResetPage = true,
|
|
manualExpandedKey = 'expanded',
|
|
plugins,
|
|
pageCount: userPageCount,
|
|
paginateExpandedRows = true,
|
|
expandSubRows = true,
|
|
state: { pageSize, pageIndex, expanded, globalFilter, filters, groupBy, sortBy },
|
|
dispatch,
|
|
data,
|
|
manualPagination,
|
|
manualGlobalFilter,
|
|
manualFilters,
|
|
manualGroupBy,
|
|
manualSortBy,
|
|
} = instance
|
|
|
|
ensurePluginOrder(
|
|
plugins,
|
|
['useGlobalFilter', 'useFilters', 'useGroupBy', 'useSortBy', 'useExpanded'],
|
|
'usePagination',
|
|
[]
|
|
)
|
|
|
|
const getAutoResetPage = useGetLatest(autoResetPage)
|
|
|
|
useMountedLayoutEffect(() => {
|
|
if (getAutoResetPage()) {
|
|
dispatch({ type: actions.resetPage })
|
|
}
|
|
}, [
|
|
dispatch,
|
|
manualPagination ? null : data,
|
|
manualPagination || manualGlobalFilter ? null : globalFilter,
|
|
manualPagination || manualFilters ? null : filters,
|
|
manualPagination || manualGroupBy ? null : groupBy,
|
|
manualPagination || manualSortBy ? null : sortBy,
|
|
])
|
|
|
|
const pageCount = manualPagination
|
|
? userPageCount
|
|
: Math.ceil(rows.length / pageSize)
|
|
|
|
const pageOptions = React.useMemo(
|
|
() => (pageCount > 0 ? [...new Array(pageCount)].map((d, i) => i) : []),
|
|
[pageCount]
|
|
)
|
|
|
|
const page = React.useMemo(() => {
|
|
let page
|
|
|
|
if (manualPagination) {
|
|
page = rows
|
|
} else {
|
|
const pageStart = pageSize * pageIndex
|
|
const pageEnd = pageStart + pageSize
|
|
|
|
page = rows.slice(pageStart, pageEnd)
|
|
}
|
|
|
|
if (paginateExpandedRows) {
|
|
return page
|
|
}
|
|
|
|
return expandRows(page, { manualExpandedKey, expanded, expandSubRows })
|
|
}, [
|
|
expandSubRows,
|
|
expanded,
|
|
manualExpandedKey,
|
|
manualPagination,
|
|
pageIndex,
|
|
pageSize,
|
|
paginateExpandedRows,
|
|
rows,
|
|
])
|
|
|
|
const canPreviousPage = pageIndex > 0
|
|
const canNextPage = pageCount === -1 || pageIndex < pageCount - 1
|
|
|
|
const gotoPage = React.useCallback(
|
|
pageIndex => {
|
|
dispatch({ type: actions.gotoPage, pageIndex })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const previousPage = React.useCallback(() => {
|
|
return gotoPage(old => old - 1)
|
|
}, [gotoPage])
|
|
|
|
const nextPage = React.useCallback(() => {
|
|
return gotoPage(old => old + 1)
|
|
}, [gotoPage])
|
|
|
|
const setPageSize = React.useCallback(
|
|
pageSize => {
|
|
dispatch({ type: actions.setPageSize, pageSize })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
Object.assign(instance, {
|
|
pageOptions,
|
|
pageCount,
|
|
page,
|
|
canPreviousPage,
|
|
canNextPage,
|
|
gotoPage,
|
|
previousPage,
|
|
nextPage,
|
|
setPageSize,
|
|
})
|
|
}
|