@propellerads/table 4.3.2 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/table.cjs.development.js +13 -12
- package/dist/table.cjs.development.js.map +1 -1
- package/dist/table.cjs.production.min.js +1 -1
- package/dist/table.cjs.production.min.js.map +1 -1
- package/dist/table.esm.js +15 -14
- package/dist/table.esm.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/package.json +2 -2
- package/src/index.tsx +117 -64
- package/src/types.tsx +2 -1
- package/src/useLoadingState.tsx +4 -2
package/src/index.tsx
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import React, {
|
|
2
|
-
FunctionComponent,
|
|
3
|
-
useEffect,
|
|
4
|
-
useMemo,
|
|
5
|
-
useRef,
|
|
2
|
+
FunctionComponent, useEffect, useMemo, useRef,
|
|
6
3
|
} from 'react';
|
|
7
4
|
import {
|
|
8
5
|
useSortBy,
|
|
9
6
|
useTable,
|
|
10
7
|
useRowSelect,
|
|
11
8
|
usePagination,
|
|
9
|
+
useExpanded,
|
|
12
10
|
useFlexLayout,
|
|
13
11
|
Column,
|
|
14
12
|
} from 'react-table';
|
|
15
13
|
|
|
16
14
|
import {
|
|
17
|
-
|
|
15
|
+
ArrowDown, ArrowUp, COLOR, SIZE,
|
|
18
16
|
} from '@propellerads/icon';
|
|
19
17
|
import Checkbox from '@propellerads/input-checkbox';
|
|
20
18
|
|
|
@@ -97,10 +95,7 @@ function getHeadContent(column: ColumnWithSort) {
|
|
|
97
95
|
return (
|
|
98
96
|
<HeadCell>
|
|
99
97
|
{column.render('Header')}
|
|
100
|
-
<
|
|
101
|
-
size={SIZE.SMALL}
|
|
102
|
-
color={COLOR.GRAY_DARK}
|
|
103
|
-
/>
|
|
98
|
+
<ArrowDown size={SIZE.SMALL} color={COLOR.GRAY_DARK} />
|
|
104
99
|
</HeadCell>
|
|
105
100
|
);
|
|
106
101
|
}
|
|
@@ -109,10 +104,7 @@ function getHeadContent(column: ColumnWithSort) {
|
|
|
109
104
|
return (
|
|
110
105
|
<HeadCell>
|
|
111
106
|
{column.render('Header')}
|
|
112
|
-
<ArrowUp
|
|
113
|
-
size={SIZE.SMALL}
|
|
114
|
-
color={COLOR.GRAY_DARK}
|
|
115
|
-
/>
|
|
107
|
+
<ArrowUp size={SIZE.SMALL} color={COLOR.GRAY_DARK} />
|
|
116
108
|
</HeadCell>
|
|
117
109
|
);
|
|
118
110
|
}
|
|
@@ -149,21 +141,30 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
149
141
|
getFooterGroupProps,
|
|
150
142
|
showLoadingState,
|
|
151
143
|
noDataMessage,
|
|
144
|
+
rowSubComponent,
|
|
152
145
|
} = props;
|
|
153
146
|
|
|
154
147
|
const memoColumns = useMemo(() => columns, [columns]);
|
|
155
148
|
|
|
156
149
|
const {loadingColumns, loadingData} = useLoadingState(
|
|
157
|
-
showLoadingState,
|
|
150
|
+
showLoadingState,
|
|
151
|
+
isLoading,
|
|
152
|
+
controlledPagination?.pageSize ?? DEFAULT_PAGE_SIZE,
|
|
153
|
+
memoColumns,
|
|
154
|
+
LoadingCellComponent,
|
|
158
155
|
);
|
|
159
156
|
|
|
160
157
|
const showLoading = showLoadingState && isLoading;
|
|
161
158
|
const hasSelectedRowsAbility = onSelectRowsChange && isFunction(onSelectRowsChange);
|
|
162
159
|
const hasManualSortBy = onSortedChange && isFunction(onSortedChange);
|
|
163
|
-
const hasControlledPagination = fetchData
|
|
160
|
+
const hasControlledPagination = fetchData
|
|
161
|
+
&& controlledPagination
|
|
162
|
+
&& Object.keys(controlledPagination).length > 0;
|
|
164
163
|
|
|
165
164
|
const options: TableOptionsProps = {
|
|
166
|
-
columns: showLoading
|
|
165
|
+
columns: showLoading
|
|
166
|
+
? (loadingColumns as Column<DefaultObject>[])
|
|
167
|
+
: memoColumns,
|
|
167
168
|
data: showLoading ? loadingData : data,
|
|
168
169
|
initialState,
|
|
169
170
|
disableSortRemove,
|
|
@@ -177,7 +178,9 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
177
178
|
|
|
178
179
|
if (hasControlledPagination) {
|
|
179
180
|
if (typeof controlledPagination?.pageCount === 'undefined') {
|
|
180
|
-
throw new Error(
|
|
181
|
+
throw new Error(
|
|
182
|
+
'You have to pass pageCount in controlledPagination data',
|
|
183
|
+
);
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
options.initialState = {
|
|
@@ -200,7 +203,10 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
200
203
|
id: 'selection',
|
|
201
204
|
disableSortBy: true,
|
|
202
205
|
Header: (instance: SelectableRowInstanceProps) => {
|
|
203
|
-
const {
|
|
206
|
+
const {
|
|
207
|
+
getToggleAllRowsSelectedProps,
|
|
208
|
+
toggleAllRowsSelected,
|
|
209
|
+
} = instance;
|
|
204
210
|
|
|
205
211
|
return (
|
|
206
212
|
<Checkbox
|
|
@@ -230,10 +236,10 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
230
236
|
},
|
|
231
237
|
};
|
|
232
238
|
|
|
233
|
-
hooks.visibleColumns.push((tableColumns: Array<StandardColumn>) =>
|
|
239
|
+
hooks.visibleColumns.push((tableColumns: Array<StandardColumn>) => [
|
|
234
240
|
newColumn,
|
|
235
241
|
...tableColumns,
|
|
236
|
-
])
|
|
242
|
+
]);
|
|
237
243
|
};
|
|
238
244
|
|
|
239
245
|
const {
|
|
@@ -249,6 +255,7 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
249
255
|
options,
|
|
250
256
|
useFlexLayout,
|
|
251
257
|
useSortBy,
|
|
258
|
+
useExpanded,
|
|
252
259
|
usePagination,
|
|
253
260
|
useRowSelect,
|
|
254
261
|
useSelect,
|
|
@@ -285,15 +292,19 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
285
292
|
|
|
286
293
|
useEffect(() => {
|
|
287
294
|
if (hasSelectedRowsAbility) {
|
|
288
|
-
onSelectRowsChange?.(
|
|
295
|
+
onSelectRowsChange?.(
|
|
296
|
+
selectedFlatRows?.map((row: StandardRow) => row.original),
|
|
297
|
+
);
|
|
289
298
|
}
|
|
290
299
|
}, [selectedRowIds]);
|
|
291
300
|
|
|
292
301
|
let pagination: JSX.Element | null = null;
|
|
293
302
|
|
|
294
303
|
if (hasDefaultPagination && hasControlledPagination) {
|
|
295
|
-
|
|
296
|
-
|
|
304
|
+
throw new Error(
|
|
305
|
+
'You have to pass either hasDefaultPagination true boolean prop or '
|
|
306
|
+
+ 'pass fetchData callback and controlledPagination data',
|
|
307
|
+
);
|
|
297
308
|
}
|
|
298
309
|
|
|
299
310
|
if (hasControlledPagination || hasDefaultPagination) {
|
|
@@ -347,9 +358,7 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
347
358
|
}
|
|
348
359
|
}
|
|
349
360
|
|
|
350
|
-
pagination =
|
|
351
|
-
<PaginationComponent {...paginationData} />
|
|
352
|
-
);
|
|
361
|
+
pagination = <PaginationComponent {...paginationData} />;
|
|
353
362
|
}
|
|
354
363
|
|
|
355
364
|
function extendSortByProps(column: ColumnWithSort) {
|
|
@@ -360,39 +369,55 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
360
369
|
if (hasManualSortBy && column.canSort && headerProps) {
|
|
361
370
|
headerProps.onClick = () => {
|
|
362
371
|
onSortedChange?.(column.id, Boolean(column.isSortedDesc));
|
|
363
|
-
setSortBy([
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
372
|
+
setSortBy([
|
|
373
|
+
{
|
|
374
|
+
id: column.id,
|
|
375
|
+
desc: !column.isSortedDesc,
|
|
376
|
+
},
|
|
377
|
+
]);
|
|
367
378
|
};
|
|
368
379
|
}
|
|
369
380
|
|
|
370
381
|
return headerProps;
|
|
371
382
|
}
|
|
372
383
|
|
|
373
|
-
const tBodyTr =
|
|
384
|
+
const tBodyTr = hasControlledPagination || hasDefaultPagination ? page : rows;
|
|
374
385
|
|
|
375
386
|
return (
|
|
376
387
|
<TableRoot className="table-root">
|
|
377
|
-
<TableLoading
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
388
|
+
<TableLoading
|
|
389
|
+
isLoading={!showLoadingState && isLoading}
|
|
390
|
+
className="table-loading"
|
|
391
|
+
>
|
|
392
|
+
<TableLoadingInner>{loadingMessage}</TableLoadingInner>
|
|
381
393
|
</TableLoading>
|
|
382
394
|
<TableWrapper ref={tableWrapperRef} className="table-wrapper">
|
|
383
395
|
<TableContent id={tableContentId} className="table-content">
|
|
384
|
-
<TableCore
|
|
396
|
+
<TableCore
|
|
397
|
+
{..._getTableProps(getTableBodyProps(getTableProps))}
|
|
398
|
+
ref={tableRef}
|
|
399
|
+
>
|
|
385
400
|
<THead className="table-head">
|
|
386
401
|
{headerGroups.map((headerGroup) => (
|
|
387
|
-
<TR
|
|
402
|
+
<TR
|
|
403
|
+
{...headerGroup.getHeaderGroupProps(
|
|
404
|
+
getTableElementProps(getHeaderGroupProps),
|
|
405
|
+
)}
|
|
406
|
+
>
|
|
388
407
|
{headerGroup.headers.map((column) => {
|
|
389
|
-
const headerProps = extendSortByProps(
|
|
408
|
+
const headerProps = extendSortByProps(
|
|
409
|
+
column,
|
|
410
|
+
) as DefaultObject;
|
|
390
411
|
|
|
391
412
|
return (
|
|
392
413
|
<TH
|
|
393
|
-
{...column.getHeaderProps(
|
|
394
|
-
|
|
395
|
-
|
|
414
|
+
{...column.getHeaderProps(
|
|
415
|
+
getTableElementInternalProps(
|
|
416
|
+
headerProps,
|
|
417
|
+
getHeaderProps,
|
|
418
|
+
mainCellGetter,
|
|
419
|
+
),
|
|
420
|
+
)}
|
|
396
421
|
>
|
|
397
422
|
{getHeadContent(column)}
|
|
398
423
|
</TH>
|
|
@@ -404,9 +429,17 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
404
429
|
{footerPlacement.includes(FOOTER_PLACEMENT.TOP) && (
|
|
405
430
|
<TFoot className="table-footer-top">
|
|
406
431
|
{footerGroups.map((group) => (
|
|
407
|
-
<TR
|
|
432
|
+
<TR
|
|
433
|
+
{...group.getFooterGroupProps(
|
|
434
|
+
getTableElementProps(getFooterGroupProps),
|
|
435
|
+
)}
|
|
436
|
+
>
|
|
408
437
|
{group.headers.map((column) => (
|
|
409
|
-
<TD
|
|
438
|
+
<TD
|
|
439
|
+
{...column.getFooterProps(
|
|
440
|
+
getTableElementProps(getFooterProps, mainCellGetter),
|
|
441
|
+
)}
|
|
442
|
+
>
|
|
410
443
|
{column.render('Footer')}
|
|
411
444
|
</TD>
|
|
412
445
|
))}
|
|
@@ -421,38 +454,58 @@ const Table: FunctionComponent<TableProps & DefaultProps> = (props) => {
|
|
|
421
454
|
|
|
422
455
|
if (isDelimiterTd) {
|
|
423
456
|
return (
|
|
424
|
-
|
|
425
|
-
<
|
|
426
|
-
<
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
457
|
+
<>
|
|
458
|
+
<TRGroup key={`group_${row.index}`}>
|
|
459
|
+
<TR {...row.getRowProps(getTableRowProps(getRowProps))}>
|
|
460
|
+
<TD
|
|
461
|
+
colSpan={visibleColumns.length}
|
|
462
|
+
{...row.cells[0].getCellProps(
|
|
463
|
+
getTableCellProps(getCellProps, cellGetter),
|
|
464
|
+
)}
|
|
465
|
+
>
|
|
466
|
+
<strong>{row.cells[0].render('Cell')}</strong>
|
|
467
|
+
</TD>
|
|
468
|
+
</TR>
|
|
469
|
+
</TRGroup>
|
|
470
|
+
{row?.isExpanded && rowSubComponent && rowSubComponent(row)}
|
|
471
|
+
</>
|
|
434
472
|
);
|
|
435
473
|
}
|
|
436
474
|
|
|
437
475
|
return (
|
|
438
|
-
|
|
439
|
-
<
|
|
440
|
-
{row.
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
476
|
+
<>
|
|
477
|
+
<TRGroup key={`group_${row.index}`}>
|
|
478
|
+
<TR {...row.getRowProps(getTableRowProps(getRowProps))}>
|
|
479
|
+
{row.cells.map((cell: StandardCell) => (
|
|
480
|
+
<TD
|
|
481
|
+
{...cell.getCellProps(
|
|
482
|
+
getTableCellProps(getCellProps, cellGetter),
|
|
483
|
+
)}
|
|
484
|
+
>
|
|
485
|
+
{cell.render('Cell')}
|
|
486
|
+
</TD>
|
|
487
|
+
))}
|
|
488
|
+
</TR>
|
|
489
|
+
</TRGroup>
|
|
490
|
+
{row?.isExpanded && rowSubComponent && rowSubComponent(row)}
|
|
491
|
+
</>
|
|
447
492
|
);
|
|
448
493
|
})}
|
|
449
494
|
</TBody>
|
|
450
495
|
{footerPlacement.includes(FOOTER_PLACEMENT.BOTTOM) && (
|
|
451
496
|
<TFoot className="table-footer-bottom">
|
|
452
497
|
{footerGroups.map((group) => (
|
|
453
|
-
<TR
|
|
498
|
+
<TR
|
|
499
|
+
{...group.getFooterGroupProps(
|
|
500
|
+
getTableElementProps(getFooterGroupProps),
|
|
501
|
+
)}
|
|
502
|
+
>
|
|
454
503
|
{group.headers.map((column) => (
|
|
455
|
-
<TD
|
|
504
|
+
<TD
|
|
505
|
+
{...column.getFooterProps(
|
|
506
|
+
getTableElementProps(getFooterProps, mainCellGetter),
|
|
507
|
+
)}
|
|
508
|
+
>
|
|
456
509
|
{column.render('Footer')}
|
|
457
510
|
</TD>
|
|
458
511
|
))}
|
package/src/types.tsx
CHANGED
|
@@ -85,6 +85,7 @@ export type TableProps = {
|
|
|
85
85
|
showLoadingState?: boolean,
|
|
86
86
|
LoadingCellComponent?: FunctionComponent<DefaultObject>,
|
|
87
87
|
noDataMessage?: string | ReactElement
|
|
88
|
+
rowSubComponent?: (row: StandardRow) => ReactElement
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
export type TableOptions = {
|
|
@@ -135,7 +136,7 @@ export type ColumnWithSort = HeaderGroup<DefaultObject> & Partial<UseSortByColum
|
|
|
135
136
|
|
|
136
137
|
export type StandardColumn = Column<DefaultObject>
|
|
137
138
|
|
|
138
|
-
export type StandardRow = Row<DefaultObject>
|
|
139
|
+
export type StandardRow = Row<DefaultObject> & { isExpanded?: boolean }
|
|
139
140
|
|
|
140
141
|
export type SelectableRow = Row<{ id: string }> & UseRowSelectRowProps<DefaultObject>
|
|
141
142
|
|
package/src/useLoadingState.tsx
CHANGED
|
@@ -10,10 +10,12 @@ const useLoadingState = (
|
|
|
10
10
|
LoadingCellComponent: FunctionComponent<DefaultObject>,
|
|
11
11
|
): LoadingState => {
|
|
12
12
|
const loadingColumns: Column<DefaultObject>[] | undefined = useMemo(() => (showLoadingState && loading ? columns
|
|
13
|
-
.map(({
|
|
13
|
+
.map(({
|
|
14
|
+
maxWidth, width, Header, accessor,
|
|
15
|
+
}: Column) => {
|
|
14
16
|
const column: Column<DefaultObject> = {
|
|
15
17
|
Cell: () => <LoadingCellComponent />,
|
|
16
|
-
accessor:
|
|
18
|
+
accessor: accessor as string,
|
|
17
19
|
};
|
|
18
20
|
if (maxWidth) {
|
|
19
21
|
column.maxWidth = maxWidth;
|