Socket
Socket
Sign inDemoInstall

react-table

Package Overview
Dependencies
8
Maintainers
2
Versions
217
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 7.0.0-rc.6 to 7.0.0-rc.7

src/makeDefaultPluginHooks.js

29

CHANGELOG.md

@@ -0,1 +1,30 @@

## 7.0.0-rc.7
Removed:
- `applyHooks` (exported but undocumented) function has been deprecated. Please use either `reduceHooks` or `loopHooks` utilities in your custom plugins now.
- `applyPropHooks` (exported but undocumented) function has been deprecated. Please use the `makePropGetter` utility in your custom plugins now.
Added:
- `reduceHooks` exported utility which is used to reduce a value through a collection of hooks. Each hook must return a value (mutation is discouraged)
- `loopHooks` exported utility which is used to loop over a collection of hooks. Hooks are not allowed to return a value (mutation is encouraged)
- `makePropGetter` exported utility which is used to create prop getters from a prop getter hook.
- `useOptions` plugin hook, which allows a plugin to reduce/modify the initial options being passed to the table
- `useFinalInstance` plugin hook, which allows a plugin access to the final table instance before it is returned to the user.
Modified:
- Prop-getter hook functions now support returning an array (in addition to the typical object of props). When an array is returned, each item in the array is smart-merged into a new props object (meaning it will intelligently compose and override styles and className)
- Prop-getter function supplied to the table have 2 new overloaded options (in addition to the typical object of props):
- `Function(props, instance, ...row/col/context) => Array<props> | props` - If a function is passed to a prop getter function, it will receive the previous props, the table instance, and potentially more context arguments. It is then be expected to return either an array of new props (to be smart-merged with styles and classes, the latest values taking priority over the previous values) or a props object (which will replace all previous props)
- `Array<props>` - If an array is passed to a prop getter function, each prop object in the array will be smart-merged with styles and classes into the props from previous hooks (with the latest values taking priority over the previous values).
- Extracted default hooks into separate file.
- Converted almost all usages of `instanceRef.current` to use `useGetLatest(instanceRef.current)` to help with avoiding memory leaks and to be more terse.
- Converted all previous prop-getter definitions to use the new `makePropGetter`
- Reorganized plugin hooks to declare as many hooks in the main plugin function as opposed to in the `useInstance` hook.
- Changed the `useInstanceBeforeDimensions` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to discourage mutation of the instance)
- Changed the `useInstance` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to discourage mutation of the instance)
- Change the `prepareRow` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to discourage mutation of the row)
## 7.0.0-rc.6

@@ -2,0 +31,0 @@

2

package.json
{
"name": "react-table",
"version": "7.0.0-rc.6",
"version": "7.0.0-rc.7",
"description": "Hooks for building lightweight, fast and extendable datagrids for React",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -24,3 +24,3 @@ ![React Table Header](https://github.com/tannerlinsley/react-table/raw/master/media/header.png)

- Lightweight (4kb - 11kb depending on features and tree-shaking)
- Lightweight (5kb - 12kb+ depending on features used and tree-shaking)
- Headless (100% customizable, Bring-your-own-UI)

@@ -39,3 +39,2 @@ - Auto out of the box, fully controllable API

- Extensible via hook-based plugin system
- <a href="https://medium.com/@tannerlinsley/why-i-wrote-react-table-and-the-problems-it-has-solved-for-nozzle-others-445c4e93d4a8#.axza4ixba" target="\_parent">"Why I wrote React Table and the problems it has solved for Nozzle.io"</a> by Tanner Linsley

@@ -42,0 +41,0 @@ ## Documentation

@@ -6,5 +6,5 @@ import React from 'react'

functionalUpdate,
mergeProps,
applyPropHooks,
useGetLatest,
useConsumeHookGetter,
makePropGetter,
} from '../utils'

@@ -18,4 +18,4 @@

export const useColumnVisibility = hooks => {
hooks.getToggleHiddenProps = []
hooks.getToggleHideAllColumnsProps = []
hooks.getToggleHiddenProps = [defualtGetToggleHiddenProps]
hooks.getToggleHideAllColumnsProps = [defualtGetToggleHideAllColumnsProps]

@@ -33,2 +33,32 @@ hooks.stateReducers.push(reducer)

const defualtGetToggleHiddenProps = (props, instance, column) => [
props,
{
onChange: e => {
column.toggleHidden(!e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: column.isVisible,
title: 'Toggle Column Visible',
},
]
const defualtGetToggleHideAllColumnsProps = (props, instance) => [
props,
{
onChange: e => {
instance.toggleHideAllColumns(!e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: !instance.allColumnsHidden && !instance.state.hiddenColumns.length,
title: 'Toggle All Columns Hidden',
indeterminate:
!instance.allColumnsHidden && instance.state.hiddenColumns.length,
},
]
function reducer(state, action, previousState, instanceRef) {

@@ -117,4 +147,2 @@ if (action.type === actions.init) {

)
return instance
}

@@ -134,29 +162,2 @@

flatHeaders.forEach(column => {
column.toggleHidden = value => {
dispatch({
type: actions.toggleHideColumn,
columnId: column.id,
value,
})
}
column.getToggleHiddenProps = props => {
return mergeProps(
{
onChange: e => {
column.toggleHidden(!e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: column.isVisible,
title: 'Toggle Column Visible',
},
applyPropHooks(getInstance().hooks.getToggleHiddenProps, getInstance()),
props
)
}
})
const toggleHideColumn = React.useCallback(

@@ -178,25 +179,37 @@ (columnId, value) =>

const getToggleHideAllColumnsProps = props => {
return mergeProps(
{
onChange: e => {
toggleHideAllColumns(!e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: !allColumnsHidden && !hiddenColumns.length,
title: 'Toggle All Columns Hidden',
indeterminate: !allColumnsHidden && hiddenColumns.length,
},
applyPropHooks(
getInstance().hooks.getToggleHideAllColumnsProps,
getInstance()
),
props
// Snapshot hook and disallow more from being added
const getToggleHideAllColumnsPropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getToggleHideAllColumnsProps'
)
const getToggleHideAllColumnsProps = makePropGetter(
getToggleHideAllColumnsPropsHooks(),
getInstance()
)
// Snapshot hook and disallow more from being added
const getToggleHiddenPropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getToggleHiddenProps'
)
flatHeaders.forEach(column => {
column.toggleHidden = value => {
dispatch({
type: actions.toggleHideColumn,
columnId: column.id,
value,
})
}
column.getToggleHiddenProps = makePropGetter(
getToggleHiddenPropsHooks(),
getInstance(),
column
)
}
})
return {
...instance,
Object.assign(instance, {
allColumnsHidden,
toggleHideColumn,

@@ -206,3 +219,3 @@ setHiddenColumns,

getToggleHideAllColumnsProps,
}
})
}

@@ -6,5 +6,5 @@ import React from 'react'

actions,
applyHooks,
applyPropHooks,
mergeProps,
reduceHooks,
loopHooks,
makePropGetter,
flexRender,

@@ -18,2 +18,4 @@ decorateColumnTree,

import makeDefaultPluginHooks from '../makeDefaultPluginHooks'
import { useColumnVisibility } from './useColumnVisibility'

@@ -30,7 +32,4 @@

export const useTable = (props, ...plugins) => {
// Destructure props
let {
data,
columns: userColumns,
function applyDefaults(props) {
const {
initialState = defaultInitialState,

@@ -40,36 +39,36 @@ defaultColumn = defaultColumnInstance,

getRowId = defaultGetRowId,
stateReducer: userStateReducer = defaultReducer,
stateReducer = defaultReducer,
useControlledState = defaultUseControlledState,
...rest
} = props
return {
...rest,
initialState,
defaultColumn,
getSubRows,
getRowId,
stateReducer,
useControlledState,
}
}
export const useTable = (props, ...plugins) => {
// Apply default props
props = applyDefaults(props)
// Add core plugins
plugins = [useColumnVisibility, ...plugins]
// The table instance
// Create the table instance
let instanceRef = React.useRef({})
Object.assign(instanceRef.current, {
// Create a getter for the instance (helps avoid a lot of potential memory leaks)
const getInstance = useGetLatest(instanceRef.current)
// Assign the props, plugins and hooks to the instance
Object.assign(getInstance(), {
...props,
plugins,
data,
hooks: {
stateReducers: [],
columns: [],
columnsDeps: [],
flatColumns: [],
flatColumnsDeps: [],
headerGroups: [],
headerGroupsDeps: [],
useInstanceBeforeDimensions: [],
useInstance: [],
useRows: [],
prepareRow: [],
getTableProps: [],
getTableBodyProps: [],
getRowProps: [],
getHeaderGroupProps: [],
getFooterGroupProps: [],
getHeaderProps: [],
getFooterProps: [],
getCellProps: [],
},
hooks: makeDefaultPluginHooks(),
})

@@ -79,8 +78,30 @@

plugins.filter(Boolean).forEach(plugin => {
plugin(instanceRef.current.hooks)
plugin(getInstance().hooks)
})
const getUseOptionsHooks = useConsumeHookGetter(
getInstance().hooks,
'useOptions'
)
// Allow useOptions hooks to modify the options coming into the table
Object.assign(
getInstance(),
reduceHooks(getUseOptionsHooks(), applyDefaults(props))
)
const {
data,
columns: userColumns,
initialState,
defaultColumn,
getSubRows,
getRowId,
stateReducer,
useControlledState,
} = getInstance()
// Snapshot hook and disallow more from being added
const getStateReducers = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'stateReducers'

@@ -90,3 +111,3 @@ )

// Setup user reducer ref
const getUserStateReducer = useGetLatest(userStateReducer)
const getStateReducer = useGetLatest(stateReducer)

@@ -106,5 +127,5 @@ // Build the reducer

// Allow the user to add their own state reducer(s)
...(Array.isArray(getUserStateReducer())
? getUserStateReducer()
: [getUserStateReducer()]),
...(Array.isArray(getStateReducer())
? getStateReducer()
: [getStateReducer()]),
].reduce(

@@ -115,3 +136,3 @@ (s, handler) => handler(s, action, state, instanceRef) || s,

},
[getStateReducers, getUserStateReducer]
[getStateReducers, getStateReducer]
)

@@ -127,13 +148,13 @@

Object.assign(instanceRef.current, {
state, // The state dispatcher
dispatch, // The resolved table state
Object.assign(getInstance(), {
state,
dispatch,
})
// Snapshot hook and disallow more from being added
const getColumns = useConsumeHookGetter(instanceRef.current.hooks, 'columns')
const getColumnsHooks = useConsumeHookGetter(getInstance().hooks, 'columns')
// Snapshot hook and disallow more from being added
const getColumnsDeps = useConsumeHookGetter(
instanceRef.current.hooks,
const getColumnsDepsHooks = useConsumeHookGetter(
getInstance().hooks,
'columnsDeps'

@@ -145,21 +166,22 @@ )

() =>
applyHooks(
getColumns(),
reduceHooks(
getColumnsHooks(),
decorateColumnTree(userColumns, defaultColumn),
instanceRef.current
getInstance()
),
[
defaultColumn,
getColumns,
getColumnsHooks,
getInstance,
userColumns,
// eslint-disable-next-line react-hooks/exhaustive-deps
...getColumnsDeps(instanceRef.current),
...getColumnsDepsHooks(getInstance()),
]
)
instanceRef.current.columns = columns
getInstance().columns = columns
// Snapshot hook and disallow more from being added
const getFlatColumns = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'flatColumns'

@@ -170,3 +192,3 @@ )

const getFlatColumnsDeps = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'flatColumnsDeps'

@@ -179,6 +201,6 @@ )

() =>
applyHooks(
reduceHooks(
getFlatColumns(),
flattenBy(columns, 'columns'),
instanceRef.current
getInstance()
),

@@ -188,12 +210,13 @@ [

getFlatColumns,
getInstance,
// eslint-disable-next-line react-hooks/exhaustive-deps
...getFlatColumnsDeps(instanceRef.current),
getFlatColumnsDeps(getInstance()),
]
)
instanceRef.current.flatColumns = flatColumns
getInstance().flatColumns = flatColumns
// Snapshot hook and disallow more from being added
const getHeaderGroups = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'headerGroups'

@@ -204,3 +227,3 @@ )

const getHeaderGroupsDeps = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'headerGroupsDeps'

@@ -212,6 +235,6 @@ )

() =>
applyHooks(
reduceHooks(
getHeaderGroups(),
makeHeaderGroups(flatColumns, defaultColumn),
instanceRef.current
getInstance()
),

@@ -222,8 +245,9 @@ [

getHeaderGroups,
getInstance,
// eslint-disable-next-line react-hooks/exhaustive-deps
...getHeaderGroupsDeps(),
...getHeaderGroupsDeps(getInstance()),
]
)
instanceRef.current.headerGroups = headerGroups
getInstance().headerGroups = headerGroups

@@ -235,3 +259,3 @@ const headers = React.useMemo(

instanceRef.current.headers = headers
getInstance().headers = headers

@@ -296,9 +320,9 @@ // Access the row model

return [accessedData, flatRows]
}, [data, getRowId, getSubRows, flatColumns])
}, [data, flatColumns, getRowId, getSubRows])
instanceRef.current.rows = rows
instanceRef.current.flatRows = flatRows
getInstance().rows = rows
getInstance().flatRows = flatRows
// Provide a flat header list for utilities
instanceRef.current.flatHeaders = headerGroups.reduce(
getInstance().flatHeaders = headerGroups.reduce(
(all, headerGroup) => [...all, ...headerGroup.headers],

@@ -310,25 +334,22 @@ []

const getUseInstanceBeforeDimensions = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'useInstanceBeforeDimensions'
)
instanceRef.current = applyHooks(
getUseInstanceBeforeDimensions(),
instanceRef.current
)
loopHooks(getUseInstanceBeforeDimensions(), getInstance())
// Header Visibility is needed by this point
calculateDimensions(instanceRef.current)
getInstance().totalColumnsWidth = calculateHeaderWidths(headers)
// Snapshot hook and disallow more from being added
const getUseInstance = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'useInstance'
)
instanceRef.current = applyHooks(getUseInstance(), instanceRef.current)
loopHooks(getUseInstance(), getInstance())
// Snapshot hook and disallow more from being added
const getHeaderPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getHeaderProps'

@@ -339,3 +360,3 @@ )

const getFooterPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getFooterProps'

@@ -346,3 +367,3 @@ )

// prop getter properties here.
instanceRef.current.flatHeaders.forEach(column => {
getInstance().flatHeaders.forEach(column => {
// Give columns/headers rendering power

@@ -357,3 +378,3 @@ column.render = (type, userProps = {}) => {

return flexRender(Comp, {
...instanceRef.current,
...getInstance(),
column,

@@ -365,22 +386,14 @@ ...userProps,

// Give columns/headers a default getHeaderProps
column.getHeaderProps = props =>
mergeProps(
{
key: ['header', column.id].join('_'),
colSpan: column.totalVisibleHeaderCount,
},
applyPropHooks(getHeaderPropsHooks(), column, instanceRef.current),
props
)
column.getHeaderProps = makePropGetter(
getHeaderPropsHooks(),
getInstance(),
column
)
// Give columns/headers a default getFooterProps
column.getFooterProps = props =>
mergeProps(
{
key: ['footer', column.id].join('_'),
colSpan: column.totalVisibleHeaderCount,
},
applyPropHooks(getFooterPropsHooks(), column, instanceRef.current),
props
)
column.getFooterProps = makePropGetter(
getFooterPropsHooks(),
getInstance(),
column
)
})

@@ -390,3 +403,3 @@

const getHeaderGroupPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getHeaderGroupProps'

@@ -396,8 +409,8 @@ )

// Snapshot hook and disallow more from being added
const getFooterGroupsPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
const getFooterGroupPropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getFooterGroupProps'
)
instanceRef.current.headerGroups = instanceRef.current.headerGroups.filter(
getInstance().headerGroups = getInstance().headerGroups.filter(
(headerGroup, i) => {

@@ -421,27 +434,15 @@ // Filter out any headers and headerGroups that don't have visible columns

if (headerGroup.headers.length) {
headerGroup.getHeaderGroupProps = (props = {}) =>
mergeProps(
{
key: [`header${i}`].join('_'),
},
applyPropHooks(
getHeaderGroupPropsHooks(),
headerGroup,
instanceRef.current
),
props
)
headerGroup.getHeaderGroupProps = makePropGetter(
getHeaderGroupPropsHooks(),
getInstance(),
headerGroup,
i
)
headerGroup.getFooterGroupProps = (props = {}) =>
mergeProps(
{
key: [`footer${i}`].join('_'),
},
applyPropHooks(
getFooterGroupsPropsHooks(),
headerGroup,
instanceRef.current
),
props
)
headerGroup.getFooterGroupProps = makePropGetter(
getFooterGroupPropsHooks(),
getInstance(),
headerGroup,
i
)

@@ -455,5 +456,3 @@ return true

instanceRef.current.footerGroups = [
...instanceRef.current.headerGroups,
].reverse()
getInstance().footerGroups = [...getInstance().headerGroups].reverse()

@@ -463,11 +462,8 @@ // Run the rows (this could be a dangerous hook with a ton of data)

// Snapshot hook and disallow more from being added
const getUseRowsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
'useRows'
)
const getUseRowsHooks = useConsumeHookGetter(getInstance().hooks, 'useRows')
instanceRef.current.rows = applyHooks(
getInstance().rows = reduceHooks(
getUseRowsHooks(),
instanceRef.current.rows,
instanceRef.current
getInstance().rows,
getInstance()
)

@@ -480,3 +476,3 @@

const getPrepareRowHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'prepareRow'

@@ -487,3 +483,3 @@ )

const getRowPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getRowProps'

@@ -494,18 +490,13 @@ )

const getCellPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getCellProps'
)
instanceRef.current.prepareRow = React.useCallback(
getInstance().prepareRow = React.useCallback(
row => {
row.getRowProps = props =>
mergeProps(
{ key: ['row', ...row.path].join('_') },
applyPropHooks(getRowPropsHooks(), row, instanceRef.current),
props
)
row.getRowProps = makePropGetter(getRowPropsHooks(), getInstance(), row)
// Build the visible cells for each row
row.cells = instanceRef.current.flatColumns
.filter(d => d.isVisible)
row.cells = getInstance()
.flatColumns.filter(d => d.isVisible)
.map(column => {

@@ -519,12 +510,7 @@ const cell = {

// Give each cell a getCellProps base
cell.getCellProps = props => {
const columnPathStr = [...row.path, column.id].join('_')
return mergeProps(
{
key: ['cell', columnPathStr].join('_'),
},
applyPropHooks(getCellPropsHooks(), cell, instanceRef.current),
props
)
}
cell.getCellProps = makePropGetter(
getCellPropsHooks(),
getInstance(),
cell
)

@@ -540,3 +526,3 @@ // Give each cell a renderer function (supports multiple renderers)

return flexRender(Comp, {
...instanceRef.current,
...getInstance(),
column,

@@ -553,5 +539,5 @@ row,

// need to apply any row specific hooks (useExpanded requires this)
applyHooks(getPrepareRowHooks(), row, instanceRef.current)
loopHooks(getPrepareRowHooks(), row, getInstance())
},
[getCellPropsHooks, getPrepareRowHooks, getRowPropsHooks]
[getCellPropsHooks, getInstance, getPrepareRowHooks, getRowPropsHooks]
)

@@ -561,31 +547,31 @@

const getTablePropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getTableProps'
)
instanceRef.current.getTableProps = userProps =>
mergeProps(
applyPropHooks(getTablePropsHooks(), instanceRef.current),
userProps
)
getInstance().getTableProps = makePropGetter(
getTablePropsHooks(),
getInstance()
)
// Snapshot hook and disallow more from being added
const getTableBodyPropsHooks = useConsumeHookGetter(
instanceRef.current.hooks,
getInstance().hooks,
'getTableBodyProps'
)
instanceRef.current.getTableBodyProps = userProps =>
mergeProps(
applyPropHooks(getTableBodyPropsHooks(), instanceRef.current),
userProps
)
getInstance().getTableBodyProps = makePropGetter(
getTableBodyPropsHooks(),
getInstance()
)
return instanceRef.current
}
// Snapshot hook and disallow more from being added
const getUseFinalInstanceHooks = useConsumeHookGetter(
getInstance().hooks,
'useFinalInstance'
)
function calculateDimensions(instance) {
const { headers } = instance
loopHooks(getUseFinalInstanceHooks(), getInstance())
instance.totalColumnsWidth = calculateHeaderWidths(headers)
return getInstance()
}

@@ -592,0 +578,0 @@

@@ -1,38 +0,15 @@

export const useAbsoluteLayout = hooks => {
hooks.useInstance.push(useInstance)
// Calculating column/cells widths
const cellStyles = {
position: 'absolute',
top: 0,
}
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
export const useAbsoluteLayout = hooks => {
hooks.getTableBodyProps.push(getRowStyles)
hooks.getRowProps.push(getRowStyles)
hooks.getHeaderGroupProps.push(getRowStyles)
const useInstance = instance => {
const {
totalColumnsWidth,
hooks: {
getRowProps,
getTableBodyProps,
getHeaderGroupProps,
getHeaderProps,
getCellProps,
},
} = instance
const rowStyles = {
style: {
position: 'relative',
width: `${totalColumnsWidth}px`,
},
}
getTableBodyProps.push(() => rowStyles)
getRowProps.push(() => rowStyles)
getHeaderGroupProps.push(() => rowStyles)
// Calculating column/cells widths
const cellStyles = {
position: 'absolute',
top: 0,
}
getHeaderProps.push(header => {
return {
hooks.getHeaderProps.push((props, instance, header) => [
props,
{
style: {

@@ -43,7 +20,8 @@ ...cellStyles,

},
}
})
},
])
getCellProps.push(cell => {
return {
hooks.getCellProps.push((props, instance, cell) => [
props,
{
style: {

@@ -54,6 +32,16 @@ ...cellStyles,

},
}
})
},
])
}
return instance
}
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
const getRowStyles = (props, instance) => [
props,
{
style: {
position: 'relative',
width: `${instance.totalColumnsWidth}px`,
},
},
]

@@ -1,30 +0,23 @@

export const useBlockLayout = hooks => {
hooks.useInstance.push(useInstance)
const cellStyles = {
display: 'inline-block',
boxSizing: 'border-box',
}
useBlockLayout.pluginName = 'useBlockLayout'
const useInstance = instance => {
const {
totalColumnsWidth,
hooks: { getRowProps, getHeaderGroupProps, getHeaderProps, getCellProps },
} = instance
const rowStyles = {
const getRowStyles = (props, instance) => [
props,
{
style: {
display: 'flex',
width: `${totalColumnsWidth}px`,
width: `${instance.totalColumnsWidth}px`,
},
}
},
]
getRowProps.push(() => rowStyles)
getHeaderGroupProps.push(() => rowStyles)
export const useBlockLayout = hooks => {
hooks.getRowProps.push(getRowStyles)
hooks.getHeaderGroupProps.push(getRowStyles)
const cellStyles = {
display: 'inline-block',
boxSizing: 'border-box',
}
getHeaderProps.push(header => {
return {
hooks.getHeaderProps.push((props, instance, header) => [
props,
{
style: {

@@ -34,7 +27,8 @@ ...cellStyles,

},
}
})
},
])
getCellProps.push(cell => {
return {
hooks.getCellProps.push((props, instance, cell) => [
props,
{
style: {

@@ -44,6 +38,6 @@ ...cellStyles,

},
}
})
},
])
}
return instance
}
useBlockLayout.pluginName = 'useBlockLayout'

@@ -77,3 +77,3 @@ import React from 'react'

const setColumnOrder = React.useCallback(
instance.setColumnOrder = React.useCallback(
columnOrder => {

@@ -84,7 +84,2 @@ return dispatch({ type: actions.setColumnOrder, columnOrder })

)
return {
...instance,
setColumnOrder,
}
}

@@ -5,4 +5,3 @@ import React from 'react'

actions,
mergeProps,
applyPropHooks,
makePropGetter,
expandRows,

@@ -12,2 +11,3 @@ useMountedLayoutEffect,

} from '../utils'
import { useConsumeHookGetter } from '../publicUtils'

@@ -19,4 +19,3 @@ // Actions

export const useExpanded = hooks => {
hooks.getExpandedToggleProps = []
hooks.getExpandedToggleProps = [defaultGetExpandedToggleProps]
hooks.stateReducers.push(reducer)

@@ -28,2 +27,16 @@ hooks.useInstance.push(useInstance)

const defaultGetExpandedToggleProps = (props, instance, row) => [
props,
{
onClick: e => {
e.persist()
row.toggleExpanded()
},
style: {
cursor: 'pointer',
},
title: 'Toggle Expanded',
},
]
// Reducer

@@ -94,28 +107,17 @@ function reducer(state, action) {

// use reference to avoid memory leak in #1608
const instanceRef = React.useRef()
instanceRef.current = instance
const getInstance = useGetLatest(instance)
const getExpandedTogglePropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getExpandedToggleProps'
)
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
row.toggleExpanded = set => instance.toggleExpandedByPath(row.path, set)
row.getExpandedToggleProps = makePropGetter(
getExpandedTogglePropsHooks(),
getInstance(),
row
)
})

@@ -133,8 +135,9 @@

return {
...instance,
Object.assign(instance, {
toggleExpandedByPath,
preExpandedRows: rows,
expandedRows,
rows: expandedRows,
expandedDepth,
rows: expandedRows,
}
})
}

@@ -141,0 +144,0 @@

@@ -120,5 +120,2 @@ import React from 'react'

const preFilteredRows = rows
const preFilteredFlatRows = flatRows
const setFilter = (columnId, filterValue) => {

@@ -269,11 +266,12 @@ dispatch({ type: actions.setFilter, columnId, filterValue })

return {
...instance,
Object.assign(instance, {
setFilter,
setAllFilters,
preFilteredRows,
preFilteredFlatRows,
preFilteredRows: rows,
preFilteredFlatRows: flatRows,
filteredRows,
filteredFlatRows,
rows: filteredRows,
flatRows: filteredFlatRows,
}
})
}

@@ -280,0 +278,0 @@

@@ -6,4 +6,3 @@ import React from 'react'

actions,
mergeProps,
applyPropHooks,
makePropGetter,
defaultGroupByFn,

@@ -15,2 +14,3 @@ getFirstDefined,

} from '../utils'
import { useConsumeHookGetter } from '../publicUtils'

@@ -22,2 +22,3 @@ // Actions

export const useGroupBy = hooks => {
hooks.getGroupByToggleProps = [defaultGetGroupByToggleProps]
hooks.stateReducers.push(reducer)

@@ -34,2 +35,18 @@ hooks.flatColumnsDeps.push((deps, instance) => [

const defaultGetGroupByToggleProps = (props, instance, header) => [
props,
{
onClick: header.canGroupBy
? e => {
e.persist()
header.toggleGroupBy()
}
: undefined,
style: {
cursor: header.canGroupBy ? 'pointer' : undefined,
},
title: 'Toggle GroupBy',
},
]
// Reducer

@@ -113,2 +130,4 @@ function reducer(state, action) {

const getInstance = useGetLatest(instance)
flatColumns.forEach(column => {

@@ -143,32 +162,13 @@ const {

hooks.getGroupByToggleProps = []
const getGroupByTogglePropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getGroupByToggleProps'
)
// use reference to avoid memory leak in #1608
const instanceRef = React.useRef()
instanceRef.current = instance
flatHeaders.forEach(header => {
const { canGroupBy } = header
header.getGroupByToggleProps = props => {
return mergeProps(
{
onClick: canGroupBy
? e => {
e.persist()
header.toggleGroupBy()
}
: undefined,
style: {
cursor: canGroupBy ? 'pointer' : undefined,
},
title: 'Toggle GroupBy',
},
applyPropHooks(
instanceRef.current.hooks.getGroupByToggleProps,
header,
instanceRef.current
),
props
)
}
header.getGroupByToggleProps = makePropGetter(
getGroupByTogglePropsHooks(),
getInstance(),
header
)
})

@@ -186,3 +186,2 @@

})
return row
})

@@ -313,4 +312,5 @@

return {
...instance,
Object.assign(instance, {
groupedRows,
groupedFlatRows,
toggleGroupBy,

@@ -320,3 +320,3 @@ rows: groupedRows,

preGroupedRows: rows,
}
})
}

@@ -171,4 +171,3 @@ import React from 'react'

return {
...instance,
Object.assign(instance, {
pageOptions,

@@ -183,5 +182,3 @@ pageCount,

setPageSize,
pageIndex,
pageSize,
}
})
}

@@ -5,6 +5,6 @@ import {

getFirstDefined,
mergeProps,
applyPropHooks,
makePropGetter,
useGetLatest,
} from '../utils'
import { useConsumeHookGetter } from '../publicUtils'

@@ -20,2 +20,3 @@ // Default Column

export const useResizeColumns = hooks => {
hooks.getResizerProps = [defaultGetResizerProps]
hooks.stateReducers.push(reducer)

@@ -25,2 +26,98 @@ hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)

const defaultGetResizerProps = (props, instance, header) => {
const { dispatch } = instance
const onResizeStart = (e, header) => {
let isTouchEvent = false
if (e.type === 'touchstart') {
// lets not respond to multiple touches (e.g. 2 or 3 fingers)
if (e.touches && e.touches.length > 1) {
return
}
isTouchEvent = true
}
const headersToResize = getLeafHeaders(header)
const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])
const clientX = isTouchEvent ? Math.round(e.touches[0].clientX) : e.clientX
const dispatchMove = clientXPos => {
dispatch({ type: actions.columnResizing, clientX: clientXPos })
}
const dispatchEnd = () => dispatch({ type: actions.columnDoneResizing })
const handlersAndEvents = {
mouse: {
moveEvent: 'mousemove',
moveHandler: e => dispatchMove(e.clientX),
upEvent: 'mouseup',
upHandler: e => {
document.removeEventListener(
'mousemove',
handlersAndEvents.mouse.moveHandler
)
document.removeEventListener(
'mouseup',
handlersAndEvents.mouse.upHandler
)
dispatchEnd()
},
},
touch: {
moveEvent: 'touchmove',
moveHandler: e => {
if (e.cancelable) {
e.preventDefault()
e.stopPropagation()
}
dispatchMove(e.touches[0].clientX)
return false
},
upEvent: 'touchend',
upHandler: e => {
document.removeEventListener(
handlersAndEvents.touch.moveEvent,
handlersAndEvents.touch.moveHandler
)
document.removeEventListener(
handlersAndEvents.touch.upEvent,
handlersAndEvents.touch.moveHandler
)
dispatchEnd()
},
},
}
const events = isTouchEvent
? handlersAndEvents.touch
: handlersAndEvents.mouse
document.addEventListener(events.moveEvent, events.moveHandler, {
passive: false,
})
document.addEventListener(events.upEvent, events.upHandler, {
passive: false,
})
dispatch({
type: actions.columnStartResizing,
columnId: header.id,
columnWidth: header.totalWidth,
headerIdWidths,
clientX,
})
}
return [
props,
{
onMouseDown: e => e.persist() || onResizeStart(e, header),
onTouchStart: e => e.persist() || onResizeStart(e, header),
style: {
cursor: 'ew-resize',
},
draggable: false,
},
]
}
useResizeColumns.pluginName = 'useResizeColumns'

@@ -94,4 +191,2 @@

const useInstanceBeforeDimensions = instance => {
instance.hooks.getResizerProps = []
const {

@@ -102,3 +197,2 @@ flatHeaders,

state: { columnResizing },
dispatch,
} = instance

@@ -114,36 +208,9 @@

const onMouseDown = (e, header) => {
const headersToResize = getLeafHeaders(header)
const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])
const getInstance = useGetLatest(instance)
const clientX = e.clientX
const getResizerPropsHooks = useConsumeHookGetter(
getInstance(),
'getResizerProps'
)
const onMouseMove = e => {
const clientX = e.clientX
dispatch({ type: actions.columnResizing, clientX })
}
const onMouseUp = e => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
dispatch({ type: actions.columnDoneResizing })
}
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
dispatch({
type: actions.columnStartResizing,
columnId: header.id,
columnWidth: header.totalWidth,
headerIdWidths,
clientX,
})
}
// use reference to avoid memory leak in #1608
const getInstance = useGetLatest(instance)
flatHeaders.forEach(header => {

@@ -161,23 +228,9 @@ const canResize = getFirstDefined(

if (canResize) {
header.getResizerProps = userProps => {
return mergeProps(
{
onMouseDown: e => e.persist() || onMouseDown(e, header),
style: {
cursor: 'ew-resize',
},
draggable: false,
},
applyPropHooks(
getInstance().hooks.getResizerProps,
header,
getInstance()
),
userProps
)
}
header.getResizerProps = makePropGetter(
getResizerPropsHooks(),
getInstance(),
header
)
}
})
return instance
}

@@ -184,0 +237,0 @@

@@ -5,7 +5,7 @@ import React from 'react'

actions,
mergeProps,
applyPropHooks,
makePropGetter,
ensurePluginOrder,
useGetLatest,
useMountedLayoutEffect,
useConsumeHookGetter,
} from '../utils'

@@ -21,5 +21,4 @@

export const useRowSelect = hooks => {
hooks.getToggleRowSelectedProps = []
hooks.getToggleAllRowsSelectedProps = []
hooks.getToggleRowSelectedProps = [defaultGetToggleRowSelectedProps]
hooks.getToggleAllRowsSelectedProps = [defaultGetToggleAllRowsSelectedProps]
hooks.stateReducers.push(reducer)

@@ -32,2 +31,41 @@ hooks.useRows.push(useRows)

const defaultGetToggleRowSelectedProps = (props, instance, row) => {
const { manualRowSelectedKey = 'isSelected' } = instance
let checked = false
if (row.original && row.original[manualRowSelectedKey]) {
checked = true
} else {
checked = row.isSelected
}
return [
props,
{
onChange: e => {
row.toggleRowSelected(e.target.checked)
},
style: {
cursor: 'pointer',
},
checked,
title: 'Toggle Row Selected',
},
]
}
const defaultGetToggleAllRowsSelectedProps = (props, instance) => [
props,
{
onChange: e => {
instance.toggleRowSelectedAll(e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: instance.isAllRowsSelected,
title: 'Toggle All Rows Selected',
},
]
function reducer(state, action, previousState, instanceRef) {

@@ -149,3 +187,2 @@ if (action.type === actions.init) {

hooks,
manualRowSelectedKey = 'isSelected',
plugins,

@@ -190,61 +227,30 @@ flatRows,

// use reference to avoid memory leak in #1608
const instanceRef = React.useRef()
instanceRef.current = instance
const getInstance = useGetLatest(instance)
const getToggleAllRowsSelectedProps = props => {
return mergeProps(
{
onChange: e => {
toggleRowSelectedAll(e.target.checked)
},
style: {
cursor: 'pointer',
},
checked: isAllRowsSelected,
title: 'Toggle All Rows Selected',
},
applyPropHooks(
instanceRef.current.hooks.getToggleAllRowsSelectedProps,
instanceRef.current
),
props
)
}
const getToggleAllRowsSelectedPropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getToggleAllRowsSelectedProps'
)
const getToggleAllRowsSelectedProps = makePropGetter(
getToggleAllRowsSelectedPropsHooks(),
getInstance()
)
const getToggleRowSelectedPropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getToggleRowSelectedProps'
)
hooks.prepareRow.push(row => {
row.toggleRowSelected = set => toggleRowSelected(row.path, set)
row.getToggleRowSelectedProps = props => {
let checked = false
if (row.original && row.original[manualRowSelectedKey]) {
checked = true
} else {
checked = row.isSelected
}
return mergeProps(
{
onChange: e => {
row.toggleRowSelected(e.target.checked)
},
style: {
cursor: 'pointer',
},
checked,
title: 'Toggle Row Selected',
},
applyPropHooks(
instanceRef.current.hooks.getToggleRowSelectedProps,
row,
instanceRef.current
),
props
)
}
return row
row.getToggleRowSelectedProps = makePropGetter(
getToggleRowSelectedPropsHooks(),
getInstance(),
row
)
})
return {
...instance,
Object.assign(instance, {
flatRowPaths,

@@ -255,3 +261,3 @@ toggleRowSelected,

isAllRowsSelected,
}
})
}

@@ -258,0 +264,0 @@

@@ -94,10 +94,2 @@ import React from 'react'

const getAutoResetRowState = useGetLatest(autoResetRowState)
useMountedLayoutEffect(() => {
if (getAutoResetRowState()) {
dispatch({ type: actions.resetRowState })
}
}, [data])
hooks.prepareRow.push(row => {

@@ -124,11 +116,16 @@ const pathKey = row.path.join('.')

}
return row
})
return {
...instance,
const getAutoResetRowState = useGetLatest(autoResetRowState)
useMountedLayoutEffect(() => {
if (getAutoResetRowState()) {
dispatch({ type: actions.resetRowState })
}
}, [data])
Object.assign(instance, {
setRowState,
setCellState,
}
})
}

@@ -7,4 +7,4 @@ import React from 'react'

defaultColumn,
mergeProps,
applyPropHooks,
makePropGetter,
useConsumeHookGetter,
getFirstDefined,

@@ -28,2 +28,3 @@ defaultOrderByFn,

export const useSortBy = hooks => {
hooks.getSortByToggleProps = [defaultGetSortByToggleProps]
hooks.stateReducers.push(reducer)

@@ -35,2 +36,25 @@ hooks.useInstance.push(useInstance)

const defaultGetSortByToggleProps = (props, instance, column) => {
const { isMultiSortEvent = e => e.shiftKey } = instance
return [
props,
{
onClick: column.canSort
? e => {
e.persist()
column.toggleSortBy(
undefined,
!instance.disableMultiSort && isMultiSortEvent(e)
)
}
: undefined,
style: {
cursor: column.canSort ? 'pointer' : undefined,
},
title: column.canSort ? 'Toggle SortBy' : undefined,
},
]
}
// Reducer

@@ -169,5 +193,3 @@ function reducer(state, action, previousState, instanceRef) {

disableSortBy,
isMultiSortEvent = e => e.shiftKey,
flatHeaders,
hooks,
state: { sortBy },

@@ -180,4 +202,2 @@ dispatch,

ensurePluginOrder(plugins, ['useFilters'], 'useSortBy', [])
// Add custom hooks
hooks.getSortByToggleProps = []

@@ -192,2 +212,7 @@ // Updates sorting based on a columnId, desc flag and multi flag

const getSortByTogglePropsHooks = useConsumeHookGetter(
getInstance().hooks,
'getSortByToggleProps'
)
// Add the getSortByToggleProps method to columns and headers

@@ -221,27 +246,7 @@ flatHeaders.forEach(column => {

column.getSortByToggleProps = props => {
return mergeProps(
{
onClick: canSort
? e => {
e.persist()
column.toggleSortBy(
undefined,
!getInstance().disableMultiSort && isMultiSortEvent(e)
)
}
: undefined,
style: {
cursor: canSort ? 'pointer' : undefined,
},
title: canSort ? 'Toggle SortBy' : undefined,
},
applyPropHooks(
getInstance().hooks.getSortByToggleProps,
column,
getInstance()
),
props
)
}
column.getSortByToggleProps = makePropGetter(
getSortByTogglePropsHooks(),
getInstance(),
column
)

@@ -339,8 +344,8 @@ const columnSort = sortBy.find(d => d.id === id)

return {
...instance,
Object.assign(instance, {
toggleSortBy,
preSortedRows: rows,
sortedRows,
rows: sortedRows,
preSortedRows: rows,
}
})
}

@@ -39,6 +39,6 @@ import React from 'react'

export const mergeProps = (...groups) => {
let props = {}
function mergeProps(...propList) {
return propList.reduce((props, next) => {
const { style, className, ...rest } = next
groups.forEach(({ style = {}, className, ...rest } = {}) => {
props = {

@@ -49,22 +49,48 @@ ...props,

...(props.style || {}),
...style,
...(style || {}),
},
className: [props.className, className].filter(Boolean).join(' '),
}
})
if (props.className === '') {
delete props.className
if (props.className === '') {
delete props.className
}
return props
}, {})
}
function handlePropGetter(prevProps, userProps, ...meta) {
// Handle a lambda, pass it the previous props
if (typeof userProps === 'function') {
return handlePropGetter({}, userProps(prevProps, ...meta))
}
return props
// Handle an array, merge each item as separate props
if (Array.isArray(userProps)) {
return mergeProps(prevProps, ...userProps)
}
// Handle an object by default, merge the two objects
return mergeProps(prevProps, userProps)
}
export const applyHooks = (hooks, initial, ...args) =>
export const makePropGetter = (hooks, ...meta) => {
return (userProps = {}) =>
[...hooks, userProps].reduce(
(prev, next) => handlePropGetter(prev, next, ...meta),
{}
)
}
export const reduceHooks = (hooks, initial, ...args) =>
hooks.reduce((prev, next) => {
const nextValue = next(prev, ...args)
if (typeof nextValue === 'undefined') {
throw new Error(
'React Table: A hook just returned undefined! This is not allowed.'
)
if (process.env.NODE_ENV !== 'production') {
if (typeof nextValue === 'undefined') {
console.info(next)
throw new Error(
'React Table: A reducer hook ☝️ just returned undefined! This is not allowed.'
)
}
}

@@ -74,4 +100,14 @@ return nextValue

export const applyPropHooks = (hooks, ...args) =>
hooks.reduce((prev, next) => mergeProps(prev, next(...args)), {})
export const loopHooks = (hooks, ...args) =>
hooks.forEach(hook => {
const nextValue = hook(...args)
if (process.env.NODE_ENV !== 'production') {
if (typeof nextValue !== 'undefined') {
console.info(hook, nextValue)
throw new Error(
'React Table: A loop-type hook ☝️ just returned a value! This is not allowed.'
)
}
}
})

@@ -84,3 +120,4 @@ export function ensurePluginOrder(plugins, befores, pluginName, afters) {

if (pluginIndex === -1) {
throw new Error(`The plugin ${pluginName} was not found in the plugin list!
if (process.env.NODE_ENV !== 'production') {
throw new Error(`The plugin "${pluginName}" was not found in the plugin list!
This usually means you need to need to name your plugin hook by setting the 'pluginName' property of the hook function, eg:

@@ -90,2 +127,3 @@

`)
}
}

@@ -98,5 +136,7 @@

if (beforeIndex > -1 && beforeIndex > pluginIndex) {
throw new Error(
`React Table: The ${pluginName} plugin hook must be placed after the ${before} plugin hook!`
)
if (process.env.NODE_ENV !== 'production') {
throw new Error(
`React Table: The ${pluginName} plugin hook must be placed after the ${before} plugin hook!`
)
}
}

@@ -107,6 +147,8 @@ })

const afterIndex = plugins.findIndex(plugin => plugin.pluginName === after)
if (afterIndex > -1 && afterIndex < pluginIndex) {
throw new Error(
`React Table: The ${pluginName} plugin hook must be placed before the ${after} plugin hook!`
)
if (process.env.NODE_ENV !== 'production') {
if (afterIndex > -1 && afterIndex < pluginIndex) {
throw new Error(
`React Table: The ${pluginName} plugin hook must be placed before the ${after} plugin hook!`
)
}
}

@@ -113,0 +155,0 @@ })

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc