mirror of
https://github.com/gosticks/react-table.git
synced 2026-07-01 10:00:03 +00:00
Convert to core hook, use new reducerHanndler/actions
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"dist/index.js": {
|
||||
"bundled": 96781,
|
||||
"minified": 46762,
|
||||
"gzipped": 12303
|
||||
"bundled": 98780,
|
||||
"minified": 48107,
|
||||
"gzipped": 12496
|
||||
},
|
||||
"dist/index.es.js": {
|
||||
"bundled": 96216,
|
||||
"minified": 46270,
|
||||
"gzipped": 12187,
|
||||
"bundled": 97724,
|
||||
"minified": 47164,
|
||||
"gzipped": 12312,
|
||||
"treeshaked": {
|
||||
"rollup": {
|
||||
"code": 78,
|
||||
"import_statements": 21
|
||||
},
|
||||
"webpack": {
|
||||
"code": 11143
|
||||
"code": 12434
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,12 +139,6 @@ The following options are supported on any column object you can pass to `column
|
||||
- Optional
|
||||
- A nested array of columns.
|
||||
- If defined, the column will act as a header group. Columns can be recursively nested as much as needed.
|
||||
- `show: Boolean | Function`
|
||||
- Optional
|
||||
- Defaults to `true`
|
||||
- If set to `false`, the column will be hidden.
|
||||
- If set to a `function`, it will be called with the current table instance and can then return `true` or `false`.
|
||||
- The data model for hidden columns is still calculated including sorting, filters, and grouping.
|
||||
- `Header: String | Function | React.Component => JSX`
|
||||
- Optional
|
||||
- Defaults to `() => null`
|
||||
@@ -253,7 +247,8 @@ The following properties are available on every `Column` object returned by the
|
||||
- `id: String`
|
||||
- The resolved column ID from either the column's `accessor` or the column's hard-coded `id` property
|
||||
- `isVisible: Boolean`
|
||||
- The resolved visible state for the column, derived from the column's `show` property
|
||||
- Whether the column should be currently visible or not.
|
||||
- Columns that are not visible are still used for sorting, filtering, etc.
|
||||
- `render: Function(type: String | Function | Component, ?props)`
|
||||
- This function is used to render content with the added context of a column.
|
||||
- The entire table `instance` will be passed to the renderer with the addition of a `column` property, containing a reference to the column
|
||||
|
||||
113
src/hooks/useColumnVisibility.js
Normal file
113
src/hooks/useColumnVisibility.js
Normal file
@@ -0,0 +1,113 @@
|
||||
import React from 'react'
|
||||
|
||||
import { actions, reducerHandlers, functionalUpdate } from '../utils'
|
||||
|
||||
const pluginName = 'useColumnVisibility'
|
||||
|
||||
actions.resetColumnVisibility = 'resetColumnVisibility'
|
||||
actions.setColumnVisibility = 'setColumnVisibility'
|
||||
actions.toggleColumnVisibility = 'toggleColumnVisibility'
|
||||
|
||||
reducerHandlers[pluginName] = (state, action) => {
|
||||
if (action.type === actions.init) {
|
||||
return {
|
||||
columnVisibility: {},
|
||||
...state,
|
||||
}
|
||||
}
|
||||
|
||||
if (action.type === actions.resetColumnVisibility) {
|
||||
return {
|
||||
...state,
|
||||
columnVisibility: {},
|
||||
}
|
||||
}
|
||||
|
||||
if (action.type === actions.setColumnVisibility) {
|
||||
if (action.columnId) {
|
||||
return {
|
||||
...state,
|
||||
columnVisibility: {
|
||||
...state.columnVisibility,
|
||||
[action.columnId]: functionalUpdate(
|
||||
action.value,
|
||||
state.columnVisibility[action.columnId]
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
columnVisibility: functionalUpdate(action.value, state.columnVisibility),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const useColumnVisibility = hooks => {
|
||||
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
useColumnVisibility.pluginName = pluginName
|
||||
|
||||
function useInstanceBeforeDimensions(instance) {
|
||||
const {
|
||||
headers,
|
||||
state: { columnVisibility },
|
||||
} = instance
|
||||
|
||||
const handleColumn = (column, parentVisible) => {
|
||||
column.isVisible = parentVisible && columnVisibility[column.id] !== false
|
||||
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
if (column.headers && column.headers.length) {
|
||||
column.headers.forEach(
|
||||
subColumn =>
|
||||
(totalVisibleHeaderCount += handleColumn(subColumn, column.isVisible))
|
||||
)
|
||||
} else {
|
||||
totalVisibleHeaderCount = column.isVisible ? 1 : 0
|
||||
}
|
||||
|
||||
column.totalVisibleHeaderCount = totalVisibleHeaderCount
|
||||
|
||||
return totalVisibleHeaderCount
|
||||
}
|
||||
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
headers.forEach(
|
||||
subHeader => (totalVisibleHeaderCount += handleColumn(subHeader, true))
|
||||
)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
function useInstance(instance) {
|
||||
const { flatHeaders, dispatch } = instance
|
||||
|
||||
flatHeaders.forEach(column => {
|
||||
column.setVisibility = value => {
|
||||
dispatch({
|
||||
action: actions.setColumnVisibility,
|
||||
columnId: column.id,
|
||||
value,
|
||||
})
|
||||
}
|
||||
|
||||
column.toggleColumnVisibility = () =>
|
||||
dispatch({ type: actions.toggleColumnVisibility, columnId: column.id })
|
||||
})
|
||||
|
||||
const setColumnVisibility = React.useCallback(
|
||||
value => dispatch({ type: actions.setColumnVisibility, value }),
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
return {
|
||||
...instance,
|
||||
setColumnVisibility,
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,22 @@ import React from 'react'
|
||||
|
||||
//
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
applyHooks,
|
||||
applyPropHooks,
|
||||
mergeProps,
|
||||
flexRender,
|
||||
decorateColumnTree,
|
||||
makeHeaderGroups,
|
||||
flattenBy
|
||||
flattenBy,
|
||||
} from '../utils'
|
||||
|
||||
import { useColumnVisibility } from './useColumnVisibility'
|
||||
|
||||
const renderErr =
|
||||
'You must specify a valid render component. This could be "column.Cell", "column.Header", "column.Filter", "column.Aggregated" or any other custom renderer component.'
|
||||
|
||||
export const actions = {
|
||||
init: 'init',
|
||||
}
|
||||
export const reducerHandlers = {}
|
||||
|
||||
const defaultInitialState = {}
|
||||
const defaultColumnInstance = {}
|
||||
const defaultReducer = (state, action, prevState) => state
|
||||
@@ -38,6 +37,8 @@ export const useTable = (props, ...plugins) => {
|
||||
debug,
|
||||
} = props
|
||||
|
||||
plugins = [useColumnVisibility, ...plugins]
|
||||
|
||||
debug = process.env.NODE_ENV === 'production' ? false : debug
|
||||
|
||||
const reducer = (state, action) => {
|
||||
@@ -234,6 +235,7 @@ export const useTable = (props, ...plugins) => {
|
||||
if (process.env.NODE_ENV !== 'production' && debug)
|
||||
console.timeEnd('hooks.useInstanceBeforeDimensions')
|
||||
|
||||
// Header Visibility is needed by this point
|
||||
calculateDimensions(instanceRef.current)
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' && debug)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import * as utils from './utils'
|
||||
export { utils }
|
||||
export { defaultColumn } from './utils'
|
||||
export { useTable, actions, reducerHandlers } from './hooks/useTable'
|
||||
export * from './utils'
|
||||
export { useTable } from './hooks/useTable'
|
||||
export { useExpanded } from './plugin-hooks/useExpanded'
|
||||
export { useFilters } from './plugin-hooks/useFilters'
|
||||
export { useGroupBy } from './plugin-hooks/useGroupBy'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import { functionalUpdate } from '../utils'
|
||||
import { reducerHandlers, functionalUpdate, actions } from '../utils'
|
||||
|
||||
const pluginName = 'useColumnOrder'
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { defaultState } from '../hooks/useTable';
|
||||
import { addActions, actions } from '../actions';
|
||||
import { determineHeaderVisibility } from '../utils';
|
||||
|
||||
addActions('setColumnVisibility');
|
||||
|
||||
defaultState.hiddenColumns = [];
|
||||
|
||||
const propTypes = {};
|
||||
|
||||
export const useColumnVisibility = (hooks) => {
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => {
|
||||
return [...deps, instance.state.hiddenColumns];
|
||||
});
|
||||
hooks.useBeforeDimensions.push(useBeforeDimensions);
|
||||
};
|
||||
|
||||
useColumnVisibility.pluginName = 'useColumnVisibility';
|
||||
|
||||
function useBeforeDimensions(instance) {
|
||||
PropTypes.checkPropTypes(propTypes, instance, 'property', 'useColumnVisibility');
|
||||
|
||||
const {
|
||||
flatHeaders,
|
||||
state: { hiddenColumns },
|
||||
setState
|
||||
} = instance;
|
||||
|
||||
const setColumnVisibility = React.useCallback(
|
||||
(updater) => {
|
||||
return setState((old) => {
|
||||
return {
|
||||
...old,
|
||||
hiddenColumns: typeof updater === 'function' ? updater(old.hiddenColumns) : updater
|
||||
};
|
||||
}, actions.setColumnVisibility);
|
||||
},
|
||||
[setState]
|
||||
);
|
||||
|
||||
flatHeaders.forEach((column) => {
|
||||
column.show = !hiddenColumns.includes(column.id);
|
||||
|
||||
column.setColumnVisibility = (show) => {
|
||||
column.show = show;
|
||||
const newhiddenColumns = new Set(hiddenColumns);
|
||||
|
||||
if (show) {
|
||||
newhiddenColumns.delete(column.id);
|
||||
} else {
|
||||
newhiddenColumns.add(column.id);
|
||||
}
|
||||
|
||||
setColumnVisibility(Array.from(newhiddenColumns));
|
||||
};
|
||||
|
||||
column.toggleColumnVisibility = () => {
|
||||
column.setColumnVisibility(!column.show);
|
||||
};
|
||||
});
|
||||
|
||||
determineHeaderVisibility(instance);
|
||||
|
||||
return {
|
||||
...instance,
|
||||
setColumnVisibility
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react'
|
||||
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
expandRows,
|
||||
safeUseLayoutEffect,
|
||||
} from '../utils'
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
|
||||
const pluginName = 'useExpanded'
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from 'react'
|
||||
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
getFirstDefined,
|
||||
isFunction,
|
||||
safeUseLayoutEffect,
|
||||
functionalUpdate,
|
||||
} from '../utils'
|
||||
import * as filterTypes from '../filterTypes'
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
|
||||
const pluginName = 'useFilters'
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
import * as aggregations from '../aggregations'
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
defaultGroupByFn,
|
||||
|
||||
@@ -2,8 +2,9 @@ import React from 'react'
|
||||
|
||||
//
|
||||
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
ensurePluginOrder,
|
||||
safeUseLayoutEffect,
|
||||
expandRows,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
defaultColumn,
|
||||
getFirstDefined,
|
||||
mergeProps,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react'
|
||||
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
ensurePluginOrder,
|
||||
safeUseLayoutEffect,
|
||||
} from '../utils'
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
|
||||
const pluginName = 'useRowSelect'
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
//
|
||||
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import { functionalUpdate, safeUseLayoutEffect } from '../utils'
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
functionalUpdate,
|
||||
safeUseLayoutEffect,
|
||||
} from '../utils'
|
||||
|
||||
const pluginName = 'useRowState'
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
import { ensurePluginOrder, defaultColumn, safeUseLayoutEffect } from '../utils'
|
||||
import { actions, reducerHandlers } from '../hooks/useTable'
|
||||
import * as sortTypes from '../sortTypes'
|
||||
import {
|
||||
actions,
|
||||
reducerHandlers,
|
||||
ensurePluginOrder,
|
||||
defaultColumn,
|
||||
safeUseLayoutEffect,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
getFirstDefined,
|
||||
@@ -11,6 +13,8 @@ import {
|
||||
isFunction,
|
||||
} from '../utils'
|
||||
|
||||
import * as sortTypes from '../sortTypes'
|
||||
|
||||
const pluginName = 'useSortBy'
|
||||
|
||||
// Actions
|
||||
|
||||
39
src/utils.js
39
src/utils.js
@@ -1,5 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
export const actions = {
|
||||
init: 'init',
|
||||
}
|
||||
|
||||
export const reducerHandlers = {}
|
||||
|
||||
export const defaultColumn = {
|
||||
Cell: ({ cell: { value = '' } }) => String(value),
|
||||
width: 150,
|
||||
@@ -175,39 +181,6 @@ export function makeHeaderGroups(flatColumns, defaultColumn) {
|
||||
return headerGroups.reverse()
|
||||
}
|
||||
|
||||
export function determineHeaderVisibility(instance) {
|
||||
const { headers } = instance
|
||||
|
||||
const handleColumn = (column, parentVisible) => {
|
||||
column.isVisible = parentVisible
|
||||
? typeof column.show === 'function'
|
||||
? column.show(instance)
|
||||
: !!column.show
|
||||
: false
|
||||
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
if (column.headers && column.headers.length) {
|
||||
column.headers.forEach(
|
||||
subColumn =>
|
||||
(totalVisibleHeaderCount += handleColumn(subColumn, column.isVisible))
|
||||
)
|
||||
} else {
|
||||
totalVisibleHeaderCount = column.isVisible ? 1 : 0
|
||||
}
|
||||
|
||||
column.totalVisibleHeaderCount = totalVisibleHeaderCount
|
||||
|
||||
return totalVisibleHeaderCount
|
||||
}
|
||||
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
headers.forEach(
|
||||
subHeader => (totalVisibleHeaderCount += handleColumn(subHeader, true))
|
||||
)
|
||||
}
|
||||
|
||||
export function getBy(obj, path, def) {
|
||||
if (!path) {
|
||||
return obj
|
||||
|
||||
Reference in New Issue
Block a user