mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 08:20:30 +00:00
Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
488da2ecc5 | ||
|
|
5f0e7cab8b | ||
|
|
e2e67ed181 | ||
|
|
c8857a2871 | ||
|
|
98583d35f3 | ||
|
|
0a1bf55a2c | ||
|
|
54b4f8a5d1 | ||
|
|
f552c94972 | ||
|
|
7ab6385839 | ||
|
|
b8ed02cadc | ||
|
|
c3e917f13b | ||
|
|
7e6d719af4 | ||
|
|
da678d0a61 | ||
|
|
c3fe4c7fd8 | ||
|
|
45036054cb | ||
|
|
8d3a97c9a2 | ||
|
|
fb0eb3646a | ||
|
|
dfad9151c3 | ||
|
|
c618542f6e | ||
|
|
670a92734e | ||
|
|
c91130075b | ||
|
|
c4a8eb147c | ||
|
|
388cb85f0a | ||
|
|
aea76facf1 | ||
|
|
f829cd0222 | ||
|
|
0a03ea3a75 | ||
|
|
0aa55dac08 | ||
|
|
15778fe467 |
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
# Using v6?
|
||||
@@ -10,13 +9,14 @@ v6 is now considered feature complete to its current abilities and limitations.
|
||||
|
||||
# Using v7?
|
||||
|
||||
Thanks for using the alpha version of React Table v7! We're very excited about it.
|
||||
Thanks for using the beta version of React Table v7! We're very excited about it.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
@@ -32,15 +32,17 @@ Use a new [react-table codesandbox](https://codesandbox.io/s/m5lxzzpz69) to repr
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 7.0.0-beta.0
|
||||
|
||||
- Massive changes to the entire project and library. Please consult the README and documentation for more information regarding these changes.
|
||||
|
||||
## 6.8.6
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
@@ -7,6 +7,9 @@ Hooks for building **lightweight, fast and extendable datagrids** for React
|
||||
<a href="https://travis-ci.org/tannerlinsley/react-table" target="\_parent">
|
||||
<img alt="" src="https://travis-ci.org/tannerlinsley/react-table.svg?branch=master" />
|
||||
</a>
|
||||
<a href="https://bundlephobia.com/result?p=react-table@next" target="\_parent">
|
||||
<img alt="" src="https://badgen.net/bundlephobia/minzip/react-table@next" />
|
||||
</a>
|
||||
<a href="https://npmjs.com/package/react-table" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/npm/dm/react-table.svg" />
|
||||
</a>
|
||||
@@ -30,7 +33,7 @@ Hooks for building **lightweight, fast and extendable datagrids** for React
|
||||
|
||||
## Features
|
||||
|
||||
- Lightweight (4kb - 11kb depending on features and tree-shaking)
|
||||
- Lightweight (4kb - 9kb depending on features and tree-shaking)
|
||||
- Headless (100% customizable, Bring-your-own-UI)
|
||||
- Auto out of the box, fully controllable API
|
||||
- Sorting (Multi and Stable)
|
||||
@@ -48,11 +51,11 @@ Hooks for building **lightweight, fast and extendable datagrids** for React
|
||||
|
||||
#### What is the current state of React Table?
|
||||
|
||||
React Table v7 is still under active development, and its API is still changing, albeit only slightly. For this reason, it is currently in an **alpha** release state. It's estimated that it will be out of alpha and into **beta** sometime during September 2019. It will then remain in beta for a short time before being released sometime in Q4 of 2019.
|
||||
React Table v7 is still under active development, and its API is still changing, albeit only slightly. For this reason, it is currently in an **beta** release state. It's estimated that it will be fully released as a stable version sometime during October 2019.
|
||||
|
||||
#### Should I use v7@alpha in production?
|
||||
#### Should I use v7@beta in production?
|
||||
|
||||
You can use it production as long as you lock in the alpha version in your package.json and also accept that the API will likely change before it's official release.
|
||||
You can use it in production as long as you lock in the beta version in your package.json and also accept that there may be unlikely, but possible bug fixes and/or API changes before it's official release.
|
||||
|
||||
#### I'm still using v6, what should I do?
|
||||
|
||||
@@ -93,7 +96,7 @@ The differences between the 2 versions are incredibly massive. Unfortunately, I
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://bjntech.com/index.html&utm_campaign=react_table" target="_blank">
|
||||
<a href="http://bjntech.com/index.html?utm_campaign=react_table" target="_blank">
|
||||
<img width='250' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/sponsor-bjn.png">
|
||||
</a>
|
||||
</td>
|
||||
@@ -172,6 +175,7 @@ The differences between the 2 versions are incredibly massive. Unfortunately, I
|
||||
<div>Dan Houle</div>
|
||||
<div>David Pickut</div>
|
||||
<div>Jordan Soltman</div>
|
||||
<div>Robert Tajnšek</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
+3
-2
@@ -427,7 +427,7 @@ The following options are supported on any `Column` object passed to the `column
|
||||
- `sortType: String | Function`
|
||||
- Used to compare 2 rows of data and order them correctly.
|
||||
- If a **function** is passed, it must be **memoized**
|
||||
- String options: `basic`, `datettime`, `alphanumeric`. Defaults to [`alphanumeric`](TODO).
|
||||
- String options: `basic`, `datetime`, `alphanumeric`. Defaults to [`alphanumeric`](TODO).
|
||||
- The resolved function from the this string/function will be used to sort the this column's data.
|
||||
- If a `string` is passed, the function with that name located on either the custom `sortTypes` option or the built-in sorting types object will be used.
|
||||
- If a `function` is passed, it will be used.
|
||||
@@ -475,13 +475,14 @@ The following properties are available on every `Column` object returned by the
|
||||
|
||||
```js
|
||||
function Table({ columns, data }) {
|
||||
// Set some default sorting state
|
||||
// Set some default sorting state. For this an additional import of useTableState is needed
|
||||
const state = useTableState({ sortBy: [{ id: 'firstName', desc: true }] })
|
||||
|
||||
const { getTableProps, headerGroups, rows, prepareRow } = useTable(
|
||||
{
|
||||
columns,
|
||||
data,
|
||||
state,
|
||||
},
|
||||
useSortBy // Use the sortBy hook
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ $ npm install react-table@next
|
||||
$ yarn add react-table@next
|
||||
```
|
||||
|
||||
> NOTE: `@next` is only required tempororarily while work on the alpha and beta versions are still shifting.
|
||||
> NOTE: `@next` is only required temporarily while work on the alpha and beta versions are still shifting.
|
||||
|
||||
To import React Table:
|
||||
|
||||
|
||||
@@ -230,17 +230,17 @@ function App() {
|
||||
|
||||
const [data, setData] = React.useState(() => makeData(20))
|
||||
const [originalData] = React.useState(data)
|
||||
const [skipPageReset, setSkipPageReset] = React.useState(false)
|
||||
|
||||
// We need to keep the table from resetting the pageIndex when we
|
||||
// Update data. So we can keep track of that flag with a ref.
|
||||
const skipPageResetRef = React.useRef(false)
|
||||
|
||||
// When our cell renderer calls updateMyData, we'll use
|
||||
// the rowIndex, columnID and new value to update the
|
||||
// original data
|
||||
const updateMyData = (rowIndex, columnID, value) => {
|
||||
// We also turn on the flag to not reset the page
|
||||
skipPageResetRef.current = true
|
||||
setSkipPageReset(true)
|
||||
setData(old =>
|
||||
old.map((row, index) => {
|
||||
if (index === rowIndex) {
|
||||
@@ -258,7 +258,7 @@ function App() {
|
||||
// so that if data actually changes when we're not
|
||||
// editing it, the page is reset
|
||||
React.useEffect(() => {
|
||||
skipPageResetRef.current = false
|
||||
setSkipPageReset(false)
|
||||
}, [data])
|
||||
|
||||
// Let's add a data resetter/randomizer to help
|
||||
@@ -272,7 +272,7 @@ function App() {
|
||||
columns={columns}
|
||||
data={data}
|
||||
updateMyData={updateMyData}
|
||||
disablePageResetOnDataChange={skipPageResetRef.current}
|
||||
disablePageResetOnDataChange={skipPageReset}
|
||||
/>
|
||||
</Styles>
|
||||
)
|
||||
|
||||
@@ -304,8 +304,8 @@ function Table({ columns, data, updateMyData, disablePageResetOnDataChange }) {
|
||||
disablePageResetOnDataChange,
|
||||
},
|
||||
useFilters,
|
||||
useSortBy,
|
||||
useGroupBy,
|
||||
useSortBy,
|
||||
useExpanded,
|
||||
usePagination,
|
||||
useRowSelect
|
||||
|
||||
@@ -61,7 +61,7 @@ function MyTable() {
|
||||
```
|
||||
|
||||
By default, the sorting will be `alphanumeric`. This can be changed in your `column` object.
|
||||
Other options include `basic` and `datettime`.
|
||||
Other options include `basic` and `datetime`.
|
||||
Note that if you're planning on sorting numbers between 0 and 1, `basic` sorting will be more accurate.
|
||||
|
||||
More information can be found in the [API Docs](/docs/api.md#useSortBy)
|
||||
|
||||
Vendored
+288
@@ -0,0 +1,288 @@
|
||||
declare module 'react-table' {
|
||||
import { ReactNode, useState } from 'react'
|
||||
|
||||
type StringKey<D> = Extract<keyof D, string>
|
||||
type IdType<D> = StringKey<D> | string
|
||||
|
||||
type SortingRule<D> = {
|
||||
id: IdType<D>
|
||||
desc: boolean
|
||||
}
|
||||
|
||||
export type SortingRules<D> = SortingRule<D>[]
|
||||
|
||||
export type SortByFn = (a: any, b: any, desc: boolean) => 0 | 1 | -1
|
||||
|
||||
export type Filters<D> = Record<IdType<D>, string>
|
||||
|
||||
export interface Cell<D = {}> extends TableInstance<D> {
|
||||
cell: { value: any }
|
||||
column: Column<D>
|
||||
row: Row<D>
|
||||
render: (type: 'Cell' | 'Aggregated', userProps?: any) => any
|
||||
isGrouped?: boolean
|
||||
isAggregated?: boolean
|
||||
isRepeatedValue?: boolean
|
||||
getCellProps: () => any
|
||||
}
|
||||
|
||||
export interface Row<D = {}> {
|
||||
index: number
|
||||
cells: Cell<D>[]
|
||||
getRowProps: (userProps?: any) => any
|
||||
original: D
|
||||
path: any[]
|
||||
values: any[]
|
||||
depth: number
|
||||
}
|
||||
|
||||
export interface UseExpandedRow<D = {}> {
|
||||
subRows?: D[]
|
||||
groupByID?: string | number
|
||||
toggleExpanded?: () => any
|
||||
isExpanded?: boolean
|
||||
isAggregated?: boolean
|
||||
}
|
||||
|
||||
export type AccessorFn<D> = (
|
||||
originalRow: D,
|
||||
index: number,
|
||||
sub: {
|
||||
subRows: [D]
|
||||
depth: number
|
||||
data: [D]
|
||||
}
|
||||
) => unknown
|
||||
|
||||
export interface HeaderColumn<D> {
|
||||
/**
|
||||
* This string/function is used to build the data model for your column.
|
||||
*/
|
||||
accessor: IdType<D> | AccessorFn<D>
|
||||
Header?: ReactNode | ((props: TableInstance<D>) => ReactNode)
|
||||
Filter?: ReactNode | ((props: TableInstance<D>) => ReactNode)
|
||||
Cell?: ReactNode | ((cell: Cell<D>) => ReactNode)
|
||||
/**
|
||||
* This is the unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc.
|
||||
*/
|
||||
id?: IdType<D>
|
||||
minWidth?: string | number
|
||||
maxWidth?: string | number
|
||||
width?: string | number
|
||||
disableSorting?: boolean
|
||||
canSortBy?: boolean
|
||||
sortByFn?: SortByFn
|
||||
defaultSortDesc?: boolean
|
||||
isAggregated?: any
|
||||
}
|
||||
|
||||
export interface Column<D> extends HeaderColumn<D> {
|
||||
show?: boolean | ((instance: TableInstance<D>) => boolean)
|
||||
columns?: Column<D>[]
|
||||
}
|
||||
|
||||
export type Page<D = {}> = Row<D>[]
|
||||
|
||||
export interface EnhancedColumn<D>
|
||||
extends Omit<Column<D>, 'columns'>,
|
||||
TableInstance<D> {
|
||||
id: IdType<D>
|
||||
column: Column<D>
|
||||
render: (type: 'Header' | 'Filter', userProps?: any) => any
|
||||
getHeaderProps: (userProps?: any) => any
|
||||
getSortByToggleProps: (userProps?: any) => any
|
||||
isSorted: boolean
|
||||
isSortedDesc: boolean
|
||||
sortedIndex: number
|
||||
isVisible: boolean
|
||||
canSort?: boolean
|
||||
}
|
||||
|
||||
export interface HeaderGroup<D = {}> {
|
||||
headers: EnhancedColumn<D>[]
|
||||
getHeaderGroupProps: (userProps?: any) => any
|
||||
}
|
||||
|
||||
export interface Hooks {
|
||||
columnsBeforeHeaderGroups: any[]
|
||||
columnsBeforeHeaderGroupsDeps: any[]
|
||||
useMain: any[]
|
||||
useColumns: any[]
|
||||
useHeaders: any[]
|
||||
useHeaderGroups: any[]
|
||||
useRows: any[]
|
||||
prepareRow: any[]
|
||||
getTableProps: any[]
|
||||
getRowProps: any[]
|
||||
getHeaderGroupProps: any[]
|
||||
getHeaderProps: any[]
|
||||
getCellProps: any[]
|
||||
}
|
||||
|
||||
export interface RowsProps {
|
||||
subRowsKey: string
|
||||
}
|
||||
|
||||
export interface FiltersProps {
|
||||
filterFn: () => void
|
||||
manualFilters: boolean
|
||||
disableFilters: boolean
|
||||
setFilter: () => any
|
||||
setAllFilters: () => any
|
||||
}
|
||||
|
||||
export interface UsePaginationState {
|
||||
pageIndex: number
|
||||
pageSize: number
|
||||
pageCount: number
|
||||
rowCount: number
|
||||
}
|
||||
|
||||
export interface UsePaginationValues<D = {}> {
|
||||
page: Page<D>
|
||||
pageIndex: number // yes, this is on instance and state
|
||||
pageSize: number // yes, this is on instance and state
|
||||
canPreviousPage: boolean
|
||||
canNextPage: boolean
|
||||
nextPage: () => any
|
||||
previousPage: () => any
|
||||
setPageSize: (size: number) => any
|
||||
pageOptions: any[]
|
||||
manualPagination: boolean
|
||||
paginateExpandedRows: boolean
|
||||
disablePageResetOnDataChange: boolean
|
||||
pageCount: number
|
||||
gotoPage: (page: number) => any
|
||||
}
|
||||
|
||||
export interface UseFiltersState<D> {
|
||||
filters?: Filters<D>
|
||||
}
|
||||
|
||||
export interface UseFiltersValues<D> {
|
||||
setFilter: (columnID: keyof D, value: string) => void
|
||||
setAllFilters: (values: Filters<D>) => void
|
||||
disableFilters: boolean
|
||||
}
|
||||
|
||||
export interface UseGroupByValues {
|
||||
groupByFn: any
|
||||
manualGroupBy: boolean
|
||||
disableGrouping: boolean
|
||||
aggregations: any
|
||||
}
|
||||
|
||||
export interface UseGroupByState {
|
||||
groupBy: string[]
|
||||
isAggregated?: boolean
|
||||
}
|
||||
|
||||
export interface UseExpandedValues {
|
||||
toggleExpanded?: () => any
|
||||
}
|
||||
|
||||
export interface UseSortbyOptions {
|
||||
sortByFn?: SortByFn
|
||||
manualSorting?: boolean
|
||||
disableSorting?: boolean
|
||||
defaultSortDesc?: boolean
|
||||
disableMultiSort?: boolean
|
||||
}
|
||||
|
||||
export interface UseSortbyState<D> {
|
||||
sortBy?: SortingRules<D>
|
||||
}
|
||||
|
||||
export interface TableInstance<D = {}> extends TableOptions<D> {
|
||||
hooks: Hooks
|
||||
rows: Row<D>[]
|
||||
columns: EnhancedColumn<D>[]
|
||||
headerGroups: HeaderGroup<D>[]
|
||||
headers: HeaderGroup<D>[]
|
||||
getTableProps: (userProps?: any) => any
|
||||
getRowProps: (userProps?: any) => any
|
||||
prepareRow: (row: Row<D>) => any
|
||||
}
|
||||
|
||||
export interface TableOptions<D = {}> {
|
||||
data: D[]
|
||||
columns: HeaderColumn<D>[]
|
||||
state: State<D>
|
||||
debug?: boolean
|
||||
loading: boolean
|
||||
defaultColumn?: Partial<Column<D>>
|
||||
}
|
||||
|
||||
// The empty definition of TableState is not an error. It provides a definition
|
||||
// for the state, that can then be extended in the users code.
|
||||
//
|
||||
// e.g.
|
||||
//
|
||||
// export interface TableState<D = {}}>
|
||||
// extends UsePaginationState,
|
||||
// UseGroupByState,
|
||||
// UseSortbyState<D>,
|
||||
// UseFiltersState<D> {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface TableState<D = {}> {}
|
||||
|
||||
export type SetState<D> = (
|
||||
updater: (old: TableState<D>) => TableState<D>,
|
||||
actions: any
|
||||
) => void
|
||||
|
||||
export type State<D> = [TableState<D>, SetState<D>]
|
||||
|
||||
export function useTable<D = {}>(
|
||||
props: TableOptions<D>,
|
||||
...plugins: any[]
|
||||
): TableInstance<D>
|
||||
|
||||
export function useFilters<D = {}>(
|
||||
props: TableOptions<D>
|
||||
): TableOptions<D> & {
|
||||
rows: Row<D>[]
|
||||
}
|
||||
|
||||
export function useSortBy<D = {}>(
|
||||
props: TableOptions<D>
|
||||
): TableOptions<D> & {
|
||||
rows: Row<D>[]
|
||||
}
|
||||
|
||||
export function useGroupBy<D = {}>(
|
||||
props: TableOptions<D>
|
||||
): TableOptions<D> & { rows: Row<D>[] }
|
||||
|
||||
export function usePagination<D = {}>(
|
||||
props: TableOptions<D>
|
||||
): UsePaginationValues<D>
|
||||
|
||||
export function useExpanded<D = {}>(
|
||||
props: TableOptions<D>
|
||||
): TableOptions<D> & {
|
||||
toggleExpandedByPath: () => any
|
||||
expandedDepth: []
|
||||
rows: Row<D>[]
|
||||
}
|
||||
|
||||
export function useTableState<D = {}>(
|
||||
initialState?: Partial<TableState<D>>,
|
||||
overriddenState?: Partial<TableState<D>>,
|
||||
options?: {
|
||||
reducer?: (
|
||||
oldState: TableState<D>,
|
||||
newState: TableState<D>,
|
||||
type: string
|
||||
) => any
|
||||
useState?: typeof useState
|
||||
}
|
||||
): State<D>
|
||||
|
||||
export const actions: Record<string, string>
|
||||
|
||||
export function addActions(...actions: string[]): void
|
||||
|
||||
export const defaultState: Record<string, any>
|
||||
}
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "7.0.0-alpha.34",
|
||||
"version": "7.0.0-beta.2",
|
||||
"description": "A fast, lightweight, opinionated table and datagrid built on React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
@@ -27,11 +27,12 @@
|
||||
"prepare": "yarn build",
|
||||
"release": "yarn publish",
|
||||
"releaseNext": "yarn publish --tag next",
|
||||
"format": "prettier ./src/**/*.{md,js,jsx,tsx} --write"
|
||||
"format": "prettier {src,src/**,examples/*/src,examples/*/src/**}/*.{md,js,jsx,tsx} --write"
|
||||
},
|
||||
"files": [
|
||||
"CHANGELOG.md",
|
||||
"src/**/*.js",
|
||||
"index.d.ts",
|
||||
"dist",
|
||||
"LICENCE",
|
||||
"package.json",
|
||||
|
||||
@@ -246,7 +246,7 @@ export const useTable = (props, ...plugins) => {
|
||||
mergeProps(
|
||||
{
|
||||
key: ['header', column.id].join('_'),
|
||||
colSpan: column.totalHeaderCount,
|
||||
colSpan: column.totalVisibleHeaderCount,
|
||||
},
|
||||
applyPropHooks(
|
||||
instanceRef.current.hooks.getHeaderProps,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { mergeProps, applyPropHooks } from '../utils'
|
||||
import { mergeProps, applyPropHooks, expandRows } from '../utils'
|
||||
import { addActions, actions } from '../actions'
|
||||
import { defaultState } from '../hooks/useTableState'
|
||||
|
||||
@@ -81,36 +81,12 @@ function useMain(instance) {
|
||||
if (process.env.NODE_ENV === 'development' && debug)
|
||||
console.info('getExpandedRows')
|
||||
|
||||
const expandedRows = []
|
||||
|
||||
// Here we do some mutation, but it's the last stage in the
|
||||
// immutable process so this is safe
|
||||
const handleRow = row => {
|
||||
const key = row.path.join('.')
|
||||
row.isExpanded =
|
||||
(row.original && row.original[manualExpandedKey]) ||
|
||||
expanded.includes(key)
|
||||
|
||||
expandedRows.push(row)
|
||||
|
||||
row.canExpand = row.subRows && !!row.subRows.length
|
||||
|
||||
if (
|
||||
paginateExpandedRows &&
|
||||
row.isExpanded &&
|
||||
row.subRows &&
|
||||
row.subRows.length
|
||||
) {
|
||||
row.subRows.forEach(handleRow)
|
||||
}
|
||||
|
||||
return row
|
||||
if (paginateExpandedRows) {
|
||||
return expandRows(rows, { manualExpandedKey, expanded })
|
||||
}
|
||||
|
||||
rows.forEach(handleRow)
|
||||
|
||||
return expandedRows
|
||||
}, [debug, rows, manualExpandedKey, expanded, paginateExpandedRows])
|
||||
return rows
|
||||
}, [debug, paginateExpandedRows, rows, manualExpandedKey, expanded])
|
||||
|
||||
const expandedDepth = findExpandedDepth(expanded)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
|
||||
//
|
||||
import { addActions, actions } from '../actions'
|
||||
import { defaultState } from '../hooks/useTableState'
|
||||
import { ensurePluginOrder, safeUseLayoutEffect } from '../utils'
|
||||
import { ensurePluginOrder, safeUseLayoutEffect, expandRows } from '../utils'
|
||||
|
||||
defaultState.pageSize = 10
|
||||
defaultState.pageIndex = 0
|
||||
@@ -31,11 +31,15 @@ function useMain(instance) {
|
||||
rows,
|
||||
manualPagination,
|
||||
disablePageResetOnDataChange,
|
||||
manualExpandedKey = 'expanded',
|
||||
debug,
|
||||
plugins,
|
||||
pageCount: userPageCount,
|
||||
paginateExpandedRows = true,
|
||||
state: [{ pageSize, pageIndex, filters, groupBy, sortBy }, setState],
|
||||
state: [
|
||||
{ pageSize, pageIndex, filters, groupBy, sortBy, expanded },
|
||||
setState,
|
||||
],
|
||||
} = instance
|
||||
|
||||
ensurePluginOrder(
|
||||
@@ -49,8 +53,15 @@ function useMain(instance) {
|
||||
|
||||
const isPageIndexMountedRef = React.useRef()
|
||||
|
||||
// Bypass any effects from firing when this changes
|
||||
const disablePageResetOnDataChangeRef = React.useRef()
|
||||
disablePageResetOnDataChangeRef.current = disablePageResetOnDataChange
|
||||
|
||||
safeUseLayoutEffect(() => {
|
||||
if (isPageIndexMountedRef.current && !disablePageResetOnDataChange) {
|
||||
if (
|
||||
isPageIndexMountedRef.current &&
|
||||
!disablePageResetOnDataChangeRef.current
|
||||
) {
|
||||
setState(
|
||||
old => ({
|
||||
...old,
|
||||
@@ -60,7 +71,7 @@ function useMain(instance) {
|
||||
)
|
||||
}
|
||||
isPageIndexMountedRef.current = true
|
||||
}, [setState, rowDep, filters, groupBy, sortBy, disablePageResetOnDataChange])
|
||||
}, [setState, rowDep, filters, groupBy, sortBy])
|
||||
|
||||
const pageCount = manualPagination
|
||||
? userPageCount
|
||||
@@ -90,57 +101,63 @@ function useMain(instance) {
|
||||
return page
|
||||
}
|
||||
|
||||
const expandedPage = []
|
||||
|
||||
const handleRow = row => {
|
||||
expandedPage.push(row)
|
||||
|
||||
if (row.subRows && row.subRows.length && row.isExpanded) {
|
||||
row.subRows.forEach(handleRow)
|
||||
}
|
||||
}
|
||||
|
||||
page.forEach(handleRow)
|
||||
|
||||
return expandedPage
|
||||
}, [debug, manualPagination, pageIndex, pageSize, paginateExpandedRows, rows])
|
||||
return expandRows(page, { manualExpandedKey, expanded })
|
||||
}, [
|
||||
debug,
|
||||
expanded,
|
||||
manualExpandedKey,
|
||||
manualPagination,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
paginateExpandedRows,
|
||||
rows,
|
||||
])
|
||||
|
||||
const canPreviousPage = pageIndex > 0
|
||||
const canNextPage = pageCount === -1 || pageIndex < pageCount - 1
|
||||
|
||||
const gotoPage = pageIndex => {
|
||||
if (process.env.NODE_ENV === 'development' && debug)
|
||||
console.info('gotoPage')
|
||||
return setState(old => {
|
||||
if (pageIndex < 0 || pageIndex > pageCount - 1) {
|
||||
return old
|
||||
}
|
||||
return {
|
||||
...old,
|
||||
pageIndex,
|
||||
}
|
||||
}, actions.pageChange)
|
||||
}
|
||||
const gotoPage = React.useCallback(
|
||||
updater => {
|
||||
if (process.env.NODE_ENV === 'development' && debug)
|
||||
console.info('gotoPage')
|
||||
return setState(old => {
|
||||
const newPageIndex =
|
||||
typeof updater === 'function' ? updater(old.pageIndex) : updater
|
||||
|
||||
const previousPage = () => {
|
||||
return gotoPage(pageIndex - 1)
|
||||
}
|
||||
if (newPageIndex < 0 || newPageIndex > pageCount - 1) {
|
||||
return old
|
||||
}
|
||||
return {
|
||||
...old,
|
||||
pageIndex: newPageIndex,
|
||||
}
|
||||
}, actions.pageChange)
|
||||
},
|
||||
[debug, pageCount, setState]
|
||||
)
|
||||
|
||||
const nextPage = () => {
|
||||
return gotoPage(pageIndex + 1)
|
||||
}
|
||||
const previousPage = React.useCallback(() => {
|
||||
return gotoPage(old => old - 1)
|
||||
}, [gotoPage])
|
||||
|
||||
const setPageSize = pageSize => {
|
||||
setState(old => {
|
||||
const topRowIndex = old.pageSize * old.pageIndex
|
||||
const pageIndex = Math.floor(topRowIndex / pageSize)
|
||||
return {
|
||||
...old,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
}
|
||||
}, actions.pageSizeChange)
|
||||
}
|
||||
const nextPage = React.useCallback(() => {
|
||||
return gotoPage(old => old + 1)
|
||||
}, [gotoPage])
|
||||
|
||||
const setPageSize = React.useCallback(
|
||||
pageSize => {
|
||||
setState(old => {
|
||||
const topRowIndex = old.pageSize * old.pageIndex
|
||||
const pageIndex = Math.floor(topRowIndex / pageSize)
|
||||
return {
|
||||
...old,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
}
|
||||
}, actions.pageSizeChange)
|
||||
},
|
||||
[setState]
|
||||
)
|
||||
|
||||
return {
|
||||
...instance,
|
||||
|
||||
@@ -38,7 +38,7 @@ function useMain(instance) {
|
||||
[]
|
||||
)
|
||||
|
||||
const isAllRowsSelected = rowPaths.length === selectedRows.length
|
||||
const isAllRowsSelected = rowPaths.length > 0 && rowPaths.length === selectedRows.length
|
||||
|
||||
const toggleRowSelectedAll = set => {
|
||||
setState(old => {
|
||||
|
||||
+56
-7
@@ -182,14 +182,27 @@ export function determineHeaderVisibility(instance) {
|
||||
: !!column.show
|
||||
: false
|
||||
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
if (column.headers && column.headers.length) {
|
||||
column.headers.forEach(subColumn =>
|
||||
handleColumn(subColumn, column.isVisible)
|
||||
column.headers.forEach(
|
||||
subColumn =>
|
||||
(totalVisibleHeaderCount += handleColumn(subColumn, column.isVisible))
|
||||
)
|
||||
} else {
|
||||
totalVisibleHeaderCount = column.isVisible ? 1 : 0
|
||||
}
|
||||
|
||||
column.totalVisibleHeaderCount = totalVisibleHeaderCount
|
||||
|
||||
return totalVisibleHeaderCount
|
||||
}
|
||||
|
||||
headers.forEach(subHeader => handleColumn(subHeader, true))
|
||||
let totalVisibleHeaderCount = 0
|
||||
|
||||
headers.forEach(
|
||||
subHeader => (totalVisibleHeaderCount += handleColumn(subHeader, true))
|
||||
)
|
||||
}
|
||||
|
||||
export function getBy(obj, path, def) {
|
||||
@@ -265,10 +278,22 @@ export function getElementDimensions(element) {
|
||||
}
|
||||
|
||||
export function flexRender(Comp, props) {
|
||||
if (typeof Comp === 'function' || typeof Comp === 'object') {
|
||||
return <Comp {...props} />
|
||||
}
|
||||
return Comp
|
||||
return isReactComponent(Comp) ? <Comp {...props} /> : Comp
|
||||
}
|
||||
|
||||
function isClassComponent(component) {
|
||||
return (
|
||||
typeof component === 'function' &&
|
||||
!!Object.getPrototypeOf(component).isReactComponent
|
||||
)
|
||||
}
|
||||
|
||||
function isFunctionComponent(component) {
|
||||
return typeof component === 'function'
|
||||
}
|
||||
|
||||
function isReactComponent(component) {
|
||||
return isClassComponent(component) || isFunctionComponent(component)
|
||||
}
|
||||
|
||||
export const mergeProps = (...groups) => {
|
||||
@@ -373,6 +398,30 @@ This usually means you need to need to name your plugin hook by setting the 'plu
|
||||
})
|
||||
}
|
||||
|
||||
export function expandRows(rows, { manualExpandedKey, expanded }) {
|
||||
const expandedRows = []
|
||||
|
||||
const handleRow = row => {
|
||||
const key = row.path.join('.')
|
||||
|
||||
row.isExpanded =
|
||||
(row.original && row.original[manualExpandedKey]) ||
|
||||
expanded.includes(key)
|
||||
|
||||
row.canExpand = row.subRows && !!row.subRows.length
|
||||
|
||||
expandedRows.push(row)
|
||||
|
||||
if (row.subRows && row.subRows.length && row.isExpanded) {
|
||||
row.subRows.forEach(handleRow)
|
||||
}
|
||||
}
|
||||
|
||||
rows.forEach(handleRow)
|
||||
|
||||
return expandedRows
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function makePathArray(obj) {
|
||||
|
||||
Reference in New Issue
Block a user