mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-23 02:10:26 +00:00
* Update utils.js * Update useTable.js * Create useColumnVisibility.js * Update useColumnVisibility.js * Update useColumnVisibility.js * Convert to core hook, use new reducerHanndler/actions * Add useColumnVisibility internal hook
161 lines
3.4 KiB
JavaScript
Executable File
161 lines
3.4 KiB
JavaScript
Executable File
import React from 'react'
|
|
|
|
import {
|
|
actions,
|
|
reducerHandlers,
|
|
mergeProps,
|
|
applyPropHooks,
|
|
expandRows,
|
|
safeUseLayoutEffect,
|
|
} from '../utils'
|
|
|
|
const pluginName = 'useExpanded'
|
|
|
|
// Actions
|
|
actions.toggleExpandedByPath = 'toggleExpandedByPath'
|
|
actions.resetExpanded = 'resetExpanded'
|
|
|
|
// Reducer
|
|
reducerHandlers[pluginName] = (state, action) => {
|
|
if (action.type === actions.init) {
|
|
return {
|
|
expanded: [],
|
|
...state,
|
|
}
|
|
}
|
|
|
|
if (action.type === actions.resetExpanded) {
|
|
return {
|
|
...state,
|
|
expanded: [],
|
|
}
|
|
}
|
|
|
|
if (action.type === actions.toggleExpandedByPath) {
|
|
const { path, expanded } = action
|
|
const key = path.join('.')
|
|
const exists = state.expanded.includes(key)
|
|
const shouldExist = typeof set !== 'undefined' ? expanded : !exists
|
|
let newExpanded = new Set(state.expanded)
|
|
|
|
if (!exists && shouldExist) {
|
|
newExpanded.add(key)
|
|
} else if (exists && !shouldExist) {
|
|
newExpanded.delete(key)
|
|
} else {
|
|
return state
|
|
}
|
|
|
|
return {
|
|
...state,
|
|
expanded: [...newExpanded.values()],
|
|
}
|
|
}
|
|
}
|
|
|
|
export const useExpanded = hooks => {
|
|
hooks.getExpandedToggleProps = []
|
|
hooks.useInstance.push(useInstance)
|
|
}
|
|
|
|
useExpanded.pluginName = pluginName
|
|
|
|
const defaultGetResetExpandedDeps = ({ data }) => [data]
|
|
|
|
function useInstance(instance) {
|
|
const {
|
|
debug,
|
|
rows,
|
|
manualExpandedKey = 'expanded',
|
|
paginateExpandedRows = true,
|
|
expandSubRows = true,
|
|
hooks,
|
|
state: { expanded },
|
|
dispatch,
|
|
getResetExpandedDeps = defaultGetResetExpandedDeps,
|
|
} = instance
|
|
|
|
// Bypass any effects from firing when this changes
|
|
const isMountedRef = React.useRef()
|
|
safeUseLayoutEffect(() => {
|
|
if (isMountedRef.current) {
|
|
dispatch({ type: actions.resetExpanded })
|
|
}
|
|
isMountedRef.current = true
|
|
}, [
|
|
dispatch,
|
|
...(getResetExpandedDeps ? getResetExpandedDeps(instance) : []),
|
|
])
|
|
|
|
const toggleExpandedByPath = (path, expanded) => {
|
|
dispatch({ type: actions.toggleExpandedByPath, path, expanded })
|
|
}
|
|
|
|
// use reference to avoid memory leak in #1608
|
|
const instanceRef = React.useRef()
|
|
instanceRef.current = instance
|
|
|
|
hooks.prepareRow.push(row => {
|
|
row.toggleExpanded = set => toggleExpandedByPath(row.path, set)
|
|
row.getExpandedToggleProps = props => {
|
|
return mergeProps(
|
|
{
|
|
onClick: e => {
|
|
e.persist()
|
|
row.toggleExpanded()
|
|
},
|
|
style: {
|
|
cursor: 'pointer',
|
|
},
|
|
title: 'Toggle Expanded',
|
|
},
|
|
applyPropHooks(
|
|
instanceRef.current.hooks.getExpandedToggleProps,
|
|
row,
|
|
instanceRef.current
|
|
),
|
|
props
|
|
)
|
|
}
|
|
return row
|
|
})
|
|
|
|
const expandedRows = React.useMemo(() => {
|
|
if (process.env.NODE_ENV !== 'production' && debug)
|
|
console.info('getExpandedRows')
|
|
|
|
if (paginateExpandedRows) {
|
|
return expandRows(rows, { manualExpandedKey, expanded, expandSubRows })
|
|
}
|
|
|
|
return rows
|
|
}, [
|
|
debug,
|
|
paginateExpandedRows,
|
|
rows,
|
|
manualExpandedKey,
|
|
expanded,
|
|
expandSubRows,
|
|
])
|
|
|
|
const expandedDepth = findExpandedDepth(expanded)
|
|
|
|
return {
|
|
...instance,
|
|
toggleExpandedByPath,
|
|
expandedDepth,
|
|
rows: expandedRows,
|
|
}
|
|
}
|
|
|
|
function findExpandedDepth(expanded) {
|
|
let maxDepth = 0
|
|
|
|
expanded.forEach(key => {
|
|
const path = key.split('.')
|
|
maxDepth = Math.max(maxDepth, path.length)
|
|
})
|
|
|
|
return maxDepth
|
|
}
|