Convert to core hook, use new reducerHanndler/actions

This commit is contained in:
Tanner Linsley
2019-12-04 01:45:05 -05:00
parent 7abc0157c0
commit 66da7e58b7
16 changed files with 164 additions and 143 deletions

View File

@@ -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
}
}
}

View File

@@ -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

View 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,
}
}

View File

@@ -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)

View File

@@ -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'

View File

@@ -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'

View File

@@ -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
};
}

View File

@@ -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'

View File

@@ -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'

View File

@@ -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,

View File

@@ -2,8 +2,9 @@ import React from 'react'
//
import { actions, reducerHandlers } from '../hooks/useTable'
import {
actions,
reducerHandlers,
ensurePluginOrder,
safeUseLayoutEffect,
expandRows,

View File

@@ -1,7 +1,8 @@
import React from 'react'
import { actions, reducerHandlers } from '../hooks/useTable'
import {
actions,
reducerHandlers,
defaultColumn,
getFirstDefined,
mergeProps,

View File

@@ -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'

View File

@@ -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'

View File

@@ -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

View File

@@ -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