Change meta signature for hooks

This commit is contained in:
Tanner Linsley 2019-12-18 11:54:43 -07:00
parent 4e08fd500e
commit 30a40aa0a2
16 changed files with 177 additions and 163 deletions

View File

@ -1,20 +1,20 @@
{
"dist/index.js": {
"bundled": 107717,
"minified": 49867,
"gzipped": 13333
"bundled": 108756,
"minified": 50398,
"gzipped": 13421
},
"dist/index.es.js": {
"bundled": 106806,
"minified": 49055,
"gzipped": 13168,
"bundled": 107845,
"minified": 49586,
"gzipped": 13253,
"treeshaked": {
"rollup": {
"code": 80,
"import_statements": 21
},
"webpack": {
"code": 8239
"code": 8168
}
}
},

View File

@ -1,3 +1,9 @@
## 7.0.0-rc.14
- Changed the function signature for all propGetter hooks to accept a single object of named meta properties instead of a variable length of meta arguments. The user props object has also been added as a property to all prop getters. For example, `hooks.getRowProps.push((props, instance, row) => [...])` is now written `hooks.getRowProps.push((props, { instance, row, userProps }) => [...])`
- Changed the function signature for all reduceHooks accept a single object of named meta properties instead of a variable length of meta arguments. For example, `hooks.flatColumns.push((flatColumns, instance) => flatColumns)` is now written `hooks.flatColumns.push((flatColumns, { instance }) => flatColumns)`
- Changed the function signature for all loopHooks accept a single object of named meta properties instead of a variable length of meta arguments. For example, `hooks.prepareRow.push((row, instance) => void)` is now written `hooks.prepareRow.push((row { instance }) => void)`
## 7.0.0-rc.13
- Added the `useControlledState` hook for plugins to manipulate the final state of the table similar to how users can

View File

@ -33,7 +33,7 @@ const Styles = styled.div`
}
`
function useControlledState(state, instance) {
function useControlledState(state, { instance }) {
return React.useMemo(() => {
if (state.groupBy.length) {
return {
@ -65,7 +65,7 @@ function Table({ columns, data }) {
// Our custom plugin to add the expander column
hooks => {
hooks.useControlledState.push(useControlledState)
hooks.flatColumns.push((columns, instance) => {
hooks.flatColumns.push((columns, { instance }) => {
if (!instance.state.groupBy.length) {
return columns
}

View File

@ -19,7 +19,7 @@ export const useColumnVisibility = hooks => {
hooks.stateReducers.push(reducer)
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
hooks.headerGroupsDeps.push((deps, instance) => [
hooks.headerGroupsDeps.push((deps, { instance }) => [
...deps,
instance.state.hiddenColumns,
])
@ -28,7 +28,7 @@ export const useColumnVisibility = hooks => {
useColumnVisibility.pluginName = 'useColumnVisibility'
const defaultGetToggleHiddenProps = (props, instance, column) => [
const defaultGetToggleHiddenProps = (props, { column }) => [
props,
{
onChange: e => {
@ -42,7 +42,7 @@ const defaultGetToggleHiddenProps = (props, instance, column) => [
},
]
const defaultGetToggleHideAllColumnsProps = (props, instance) => [
const defaultGetToggleHideAllColumnsProps = (props, { instance }) => [
props,
{
onChange: e => {
@ -184,7 +184,7 @@ function useInstance(instance) {
const getToggleHideAllColumnsProps = makePropGetter(
getToggleHideAllColumnsPropsHooks(),
getInstance()
{ instance: getInstance() }
)
// Snapshot hook and disallow more from being added
@ -202,11 +202,10 @@ function useInstance(instance) {
})
}
column.getToggleHiddenProps = makePropGetter(
getToggleHiddenPropsHooks(),
getInstance(),
column
)
column.getToggleHiddenProps = makePropGetter(getToggleHiddenPropsHooks(), {
instance: getInstance(),
column,
})
})
Object.assign(instance, {

View File

@ -143,7 +143,7 @@ export const useTable = (props, ...plugins) => {
const state = reduceHooks(
[...getUseControlledStateHooks(), useControlledState],
reducerState,
getInstance()
{ instance: getInstance() }
)
Object.assign(getInstance(), {
@ -164,7 +164,9 @@ export const useTable = (props, ...plugins) => {
let columns = React.useMemo(
() =>
decorateColumnTree(
reduceHooks(getColumnsHooks(), userColumns, getInstance()),
reduceHooks(getColumnsHooks(), userColumns, {
instance: getInstance(),
}),
defaultColumn
),
[
@ -173,7 +175,7 @@ export const useTable = (props, ...plugins) => {
getInstance,
userColumns,
// eslint-disable-next-line react-hooks/exhaustive-deps
...reduceHooks(getColumnsDepsHooks(), [], getInstance()),
...reduceHooks(getColumnsDepsHooks(), [], { instance: getInstance() }),
]
)
@ -263,13 +265,14 @@ export const useTable = (props, ...plugins) => {
// have been access, and allow hooks to decorate
// those columns (and trigger this memoization via deps)
flatColumns = React.useMemo(
() => reduceHooks(flatColumnsHooks(), flatColumns, getInstance()),
() =>
reduceHooks(flatColumnsHooks(), flatColumns, { instance: getInstance() }),
[
flatColumns,
flatColumnsHooks,
getInstance,
// eslint-disable-next-line react-hooks/exhaustive-deps
...reduceHooks(flatColumnsDepsHooks(), [], getInstance()),
...reduceHooks(flatColumnsDepsHooks(), [], { instance: getInstance() }),
]
)
@ -301,7 +304,7 @@ export const useTable = (props, ...plugins) => {
getHeaderGroups,
getInstance,
// eslint-disable-next-line react-hooks/exhaustive-deps
...reduceHooks(getHeaderGroupsDeps(), [], getInstance()),
...reduceHooks(getHeaderGroupsDeps(), [], { instance: getInstance() }),
]
)
@ -367,18 +370,16 @@ export const useTable = (props, ...plugins) => {
column.render = makeRenderer(getInstance(), column)
// Give columns/headers a default getHeaderProps
column.getHeaderProps = makePropGetter(
getHeaderPropsHooks(),
getInstance(),
column
)
column.getHeaderProps = makePropGetter(getHeaderPropsHooks(), {
instance: getInstance(),
column,
})
// Give columns/headers a default getFooterProps
column.getFooterProps = makePropGetter(
getFooterPropsHooks(),
getInstance(),
column
)
column.getFooterProps = makePropGetter(getFooterPropsHooks(), {
instance: getInstance(),
column,
})
}
)
@ -415,16 +416,12 @@ export const useTable = (props, ...plugins) => {
if (headerGroup.headers.length) {
headerGroup.getHeaderGroupProps = makePropGetter(
getHeaderGroupPropsHooks(),
getInstance(),
headerGroup,
i
{ instance: getInstance(), headerGroup, index: i }
)
headerGroup.getFooterGroupProps = makePropGetter(
getFooterGroupPropsHooks(),
getInstance(),
headerGroup,
i
{ instance: getInstance(), headerGroup, index: i }
)
return true
@ -441,11 +438,9 @@ export const useTable = (props, ...plugins) => {
// Snapshot hook and disallow more from being added
const getUseRowsHooks = useConsumeHookGetter(getInstance().hooks, 'useRows')
getInstance().rows = reduceHooks(
getUseRowsHooks(),
getInstance().rows,
getInstance()
)
getInstance().rows = reduceHooks(getUseRowsHooks(), getInstance().rows, {
instance: getInstance(),
})
// The prepareRow function is absolutely necessary and MUST be called on
// any rows the user wishes to be displayed.
@ -473,7 +468,10 @@ export const useTable = (props, ...plugins) => {
getInstance().prepareRow = React.useCallback(
row => {
row.getRowProps = makePropGetter(getRowPropsHooks(), getInstance(), row)
row.getRowProps = makePropGetter(getRowPropsHooks(), {
instance: getInstance(),
row,
})
// Build the visible cells for each row
row.allCells = flatColumns.map(column => {
@ -484,11 +482,10 @@ export const useTable = (props, ...plugins) => {
}
// Give each cell a getCellProps base
cell.getCellProps = makePropGetter(
getCellPropsHooks(),
getInstance(),
cell
)
cell.getCellProps = makePropGetter(getCellPropsHooks(), {
instance: getInstance(),
cell,
})
// Give each cell a renderer function (supports multiple renderers)
cell.render = makeRenderer(getInstance(), column, {
@ -499,10 +496,12 @@ export const useTable = (props, ...plugins) => {
return cell
})
row.cells = reduceHooks(cellsHooks(), row.allCells, getInstance())
row.cells = reduceHooks(cellsHooks(), row.allCells, {
instance: getInstance(),
})
// need to apply any row specific hooks (useExpanded requires this)
loopHooks(getPrepareRowHooks(), row, getInstance())
loopHooks(getPrepareRowHooks(), row, { instance: getInstance() })
},
[
getRowPropsHooks,
@ -520,10 +519,9 @@ export const useTable = (props, ...plugins) => {
'getTableProps'
)
getInstance().getTableProps = makePropGetter(
getTablePropsHooks(),
getInstance()
)
getInstance().getTableProps = makePropGetter(getTablePropsHooks(), {
instance: getInstance(),
})
// Snapshot hook and disallow more from being added
const getTableBodyPropsHooks = useConsumeHookGetter(
@ -531,10 +529,9 @@ export const useTable = (props, ...plugins) => {
'getTableBodyProps'
)
getInstance().getTableBodyProps = makePropGetter(
getTableBodyPropsHooks(),
getInstance()
)
getInstance().getTableBodyProps = makePropGetter(getTableBodyPropsHooks(), {
instance: getInstance(),
})
// Snapshot hook and disallow more from being added
const getUseFinalInstanceHooks = useConsumeHookGetter(

View File

@ -1,33 +1,33 @@
const defaultCells = cell => cell.filter(d => d.column.isVisible)
const defaultGetHeaderProps = (props, instance, column) => ({
const defaultGetHeaderProps = (props, { column }) => ({
key: `header_${column.id}`,
colSpan: column.totalVisibleHeaderCount,
...props,
})
const defaultGetFooterProps = (props, instance, column) => ({
const defaultGetFooterProps = (props, { column }) => ({
key: `footer_${column.id}`,
colSpan: column.totalVisibleHeaderCount,
...props,
})
const defaultGetHeaderGroupProps = (props, instance, headerGroup, index) => ({
const defaultGetHeaderGroupProps = (props, { index }) => ({
key: `headerGroup_${index}`,
...props,
})
const defaultGetFooterGroupProps = (props, instance, headerGroup, index) => ({
const defaultGetFooterGroupProps = (props, { index }) => ({
key: `footerGroup_${index}`,
...props,
})
const defaultGetRowProps = (props, instance, row) => ({
const defaultGetRowProps = (props, { row }) => ({
key: `row_${row.id}`,
...props,
})
const defaultGetCellProps = (props, instance, cell) => ({
const defaultGetCellProps = (props, { cell }) => ({
...props,
key: `cell_${cell.row.id}_${cell.column.id}`,
})

View File

@ -11,18 +11,18 @@ export const useAbsoluteLayout = hooks => {
hooks.getHeaderGroupProps.push(getRowStyles)
hooks.useInstance.push(useInstance)
hooks.getHeaderProps.push((props, instance, header) => [
hooks.getHeaderProps.push((props, { column }) => [
props,
{
style: {
...cellStyles,
left: `${header.totalLeft}px`,
width: `${header.totalWidth}px`,
left: `${column.totalLeft}px`,
width: `${column.totalWidth}px`,
},
},
])
hooks.getCellProps.push((props, instance, cell) => [
hooks.getCellProps.push((props, { cell }) => [
props,
{
style: {
@ -36,7 +36,7 @@ export const useAbsoluteLayout = hooks => {
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
const getRowStyles = (props, instance) => [
const getRowStyles = (props, { instance }) => [
props,
{
style: {

View File

@ -3,7 +3,7 @@ const cellStyles = {
boxSizing: 'border-box',
}
const getRowStyles = (props, instance) => [
const getRowStyles = (props, { instance }) => [
props,
{
style: {
@ -17,17 +17,17 @@ export const useBlockLayout = hooks => {
hooks.getRowProps.push(getRowStyles)
hooks.getHeaderGroupProps.push(getRowStyles)
hooks.getHeaderProps.push((props, instance, header) => [
hooks.getHeaderProps.push((props, { column }) => [
props,
{
style: {
...cellStyles,
width: `${header.totalWidth}px`,
width: `${column.totalWidth}px`,
},
},
])
hooks.getCellProps.push((props, instance, cell) => [
hooks.getCellProps.push((props, { cell }) => [
props,
{
style: {

View File

@ -8,7 +8,7 @@ actions.setColumnOrder = 'setColumnOrder'
export const useColumnOrder = hooks => {
hooks.stateReducers.push(reducer)
hooks.flatColumnsDeps.push((deps, instance) => {
hooks.flatColumnsDeps.push((deps, { instance }) => {
return [...deps, instance.state.columnOrder]
})
hooks.flatColumns.push(flatColumns)
@ -40,11 +40,14 @@ function reducer(state, action, previousState, instance) {
}
}
function flatColumns(columns, instance) {
const {
state: { columnOrder },
} = instance
function flatColumns(
columns,
{
instance: {
state: { columnOrder },
},
}
) {
// If there is no order, return the normal columns
if (!columnOrder || !columnOrder.length) {
return columns

View File

@ -23,7 +23,7 @@ export const useExpanded = hooks => {
useExpanded.pluginName = 'useExpanded'
const defaultGetExpandedToggleProps = (props, instance, row) => [
const defaultGetExpandedToggleProps = (props, { row }) => [
props,
{
onClick: e => {
@ -124,11 +124,10 @@ function useInstance(instance) {
hooks.prepareRow.push(row => {
row.toggleExpanded = set => instance.toggleExpanded(row.id, set)
row.getExpandedToggleProps = makePropGetter(
getExpandedTogglePropsHooks(),
getInstance(),
row
)
row.getExpandedToggleProps = makePropGetter(getExpandedTogglePropsHooks(), {
instance: getInstance(),
row,
})
})
const expandedRows = React.useMemo(() => {

View File

@ -1,50 +1,53 @@
export function useFlexLayout(hooks) {
hooks.getTableBodyProps.push((props, instance) => [
props,
{
style: {
minWidth: `${instance.totalColumnsWidth}px`,
},
},
])
const getRowStyles = (props, instance) => [
props,
{
style: {
display: 'flex',
flex: '1 0 auto',
minWidth: `${instance.totalColumnsMinWidth}px`,
},
},
]
hooks.getTableBodyProps.push(getTableBodyProps)
hooks.getRowProps.push(getRowStyles)
hooks.getHeaderGroupProps.push(getRowStyles)
hooks.getHeaderProps.push((props, instance, header) => [
props,
{
style: {
boxSizing: 'border-box',
flex: `${header.totalWidth} 0 auto`,
minWidth: `${header.totalMinWidth}px`,
width: `${header.totalWidth}px`,
},
},
])
hooks.getCellProps.push((props, instance, cell) => [
props,
{
style: {
boxSizing: 'border-box',
flex: `${cell.column.totalWidth} 0 auto`,
minWidth: `${cell.column.totalMinWidth}px`,
width: `${cell.column.totalWidth}px`,
},
},
])
hooks.getHeaderProps.push(getHeaderProps)
hooks.getCellProps.push(getCellProps)
}
useFlexLayout.pluginName = 'useFlexLayout'
const getTableBodyProps = (props, { instance }) => [
props,
{
style: {
minWidth: `${instance.totalColumnsWidth}px`,
},
},
]
const getRowStyles = (props, { instance }) => [
props,
{
style: {
display: 'flex',
flex: '1 0 auto',
minWidth: `${instance.totalColumnsMinWidth}px`,
},
},
]
const getHeaderProps = (props, { column }) => [
props,
{
style: {
boxSizing: 'border-box',
flex: `${column.totalWidth} 0 auto`,
minWidth: `${column.totalMinWidth}px`,
width: `${column.totalWidth}px`,
},
},
]
const getCellProps = (props, { cell }) => [
props,
{
style: {
boxSizing: 'border-box',
flex: `${cell.column.totalWidth} 0 auto`,
minWidth: `${cell.column.totalMinWidth}px`,
width: `${cell.column.totalWidth}px`,
},
},
]

View File

@ -19,7 +19,7 @@ actions.toggleGroupBy = 'toggleGroupBy'
export const useGroupBy = hooks => {
hooks.getGroupByToggleProps = [defaultGetGroupByToggleProps]
hooks.stateReducers.push(reducer)
hooks.flatColumnsDeps.push((deps, instance) => [
hooks.flatColumnsDeps.push((deps, { instance }) => [
...deps,
instance.state.groupBy,
])
@ -29,7 +29,7 @@ export const useGroupBy = hooks => {
useGroupBy.pluginName = 'useGroupBy'
const defaultGetGroupByToggleProps = (props, instance, header) => [
const defaultGetGroupByToggleProps = (props, { header }) => [
props,
{
onClick: header.canGroupBy
@ -81,7 +81,14 @@ function reducer(state, action, previousState, instance) {
}
}
function flatColumns(flatColumns, { state: { groupBy } }) {
function flatColumns(
flatColumns,
{
instance: {
state: { groupBy },
},
}
) {
// Sort grouped columns to the start of the column list
// before the headers are built
@ -160,8 +167,7 @@ function useInstance(instance) {
flatHeaders.forEach(header => {
header.getGroupByToggleProps = makePropGetter(
getGroupByTogglePropsHooks(),
getInstance(),
header
{ instance: getInstance(), header }
)
})

View File

@ -26,7 +26,7 @@ export const useResizeColumns = hooks => {
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
}
const defaultGetResizerProps = (props, instance, header) => {
const defaultGetResizerProps = (props, { instance, header }) => {
const { dispatch } = instance
const onResizeStart = (e, header) => {
@ -215,11 +215,10 @@ const useInstanceBeforeDimensions = instance => {
header.isResizing = columnResizing.isResizingColumn === header.id
if (canResize) {
header.getResizerProps = makePropGetter(
getResizerPropsHooks(),
getInstance(),
header
)
header.getResizerProps = makePropGetter(getResizerPropsHooks(), {
instance: getInstance(),
header,
})
}
})
}

View File

@ -26,7 +26,7 @@ export const useRowSelect = hooks => {
useRowSelect.pluginName = pluginName
const defaultGetToggleRowSelectedProps = (props, instance, row) => {
const defaultGetToggleRowSelectedProps = (props, { instance, row }) => {
const { manualRowSelectedKey = 'isSelected' } = instance
let checked = false
@ -52,7 +52,7 @@ const defaultGetToggleRowSelectedProps = (props, instance, row) => {
]
}
const defaultGetToggleAllRowsSelectedProps = (props, instance) => [
const defaultGetToggleAllRowsSelectedProps = (props, { instance }) => [
props,
{
onChange: e => {
@ -153,7 +153,7 @@ function reducer(state, action, previousState, instance) {
}
}
function useRows(rows, instance) {
function useRows(rows, { instance }) {
const {
state: { selectedRowIds },
} = instance
@ -242,7 +242,7 @@ function useInstance(instance) {
const getToggleAllRowsSelectedProps = makePropGetter(
getToggleAllRowsSelectedPropsHooks(),
getInstance()
{ instance: getInstance() }
)
const getToggleRowSelectedPropsHooks = useConsumeHookGetter(
@ -255,8 +255,7 @@ function useInstance(instance) {
row.getToggleRowSelectedProps = makePropGetter(
getToggleRowSelectedPropsHooks(),
getInstance(),
row
{ instance: getInstance(), row }
)
})

View File

@ -31,7 +31,7 @@ export const useSortBy = hooks => {
useSortBy.pluginName = 'useSortBy'
const defaultGetSortByToggleProps = (props, instance, column) => {
const defaultGetSortByToggleProps = (props, { instance, column }) => {
const { isMultiSortEvent = e => e.shiftKey } = instance
return [
@ -237,11 +237,10 @@ function useInstance(instance) {
}
}
column.getSortByToggleProps = makePropGetter(
getSortByTogglePropsHooks(),
getInstance(),
column
)
column.getSortByToggleProps = makePropGetter(getSortByTogglePropsHooks(), {
instance: getInstance(),
column,
})
const columnSort = sortBy.find(d => d.id === id)
column.isSorted = !!columnSort

View File

@ -67,10 +67,10 @@ function mergeProps(...propList) {
}, {})
}
function handlePropGetter(prevProps, userProps, ...meta) {
function handlePropGetter(prevProps, userProps, meta) {
// Handle a lambda, pass it the previous props
if (typeof userProps === 'function') {
return handlePropGetter({}, userProps(prevProps, ...meta))
return handlePropGetter({}, userProps(prevProps, meta))
}
// Handle an array, merge each item as separate props
@ -82,17 +82,21 @@ function handlePropGetter(prevProps, userProps, ...meta) {
return mergeProps(prevProps, userProps)
}
export const makePropGetter = (hooks, ...meta) => {
export const makePropGetter = (hooks, meta = {}) => {
return (userProps = {}) =>
[...hooks, userProps].reduce(
(prev, next) => handlePropGetter(prev, next, ...meta),
(prev, next) =>
handlePropGetter(prev, next, {
...meta,
userProps,
}),
{}
)
}
export const reduceHooks = (hooks, initial, ...args) =>
export const reduceHooks = (hooks, initial, meta = {}) =>
hooks.reduce((prev, next) => {
const nextValue = next(prev, ...args)
const nextValue = next(prev, meta)
if (process.env.NODE_ENV !== 'production') {
if (typeof nextValue === 'undefined') {
console.info(next)
@ -104,9 +108,9 @@ export const reduceHooks = (hooks, initial, ...args) =>
return nextValue
}, initial)
export const loopHooks = (hooks, ...args) =>
export const loopHooks = (hooks, meta = {}) =>
hooks.forEach(hook => {
const nextValue = hook(...args)
const nextValue = hook(meta)
if (process.env.NODE_ENV !== 'production') {
if (typeof nextValue !== 'undefined') {
console.info(hook, nextValue)