@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/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
- ArrowDownFull, ArrowUp, COLOR, SIZE,
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
- <ArrowDownFull
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, isLoading, controlledPagination?.pageSize ?? DEFAULT_PAGE_SIZE, memoColumns, LoadingCellComponent,
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 && controlledPagination && Object.keys(controlledPagination).length > 0;
160
+ const hasControlledPagination = fetchData
161
+ && controlledPagination
162
+ && Object.keys(controlledPagination).length > 0;
164
163
 
165
164
  const options: TableOptionsProps = {
166
- columns: showLoading ? (loadingColumns as Column<DefaultObject>[]) : memoColumns,
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('You have to pass pageCount in controlledPagination data');
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 {getToggleAllRowsSelectedProps, toggleAllRowsSelected} = instance;
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?.(selectedFlatRows?.map((row: StandardRow) => row.original));
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
- // eslint-disable-next-line max-len
296
- throw new Error('You have to pass either hasDefaultPagination true boolean prop or pass fetchData callback and controlledPagination data');
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
- id: column.id,
365
- desc: !column.isSortedDesc,
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 = (hasControlledPagination || hasDefaultPagination) ? page : rows;
384
+ const tBodyTr = hasControlledPagination || hasDefaultPagination ? page : rows;
374
385
 
375
386
  return (
376
387
  <TableRoot className="table-root">
377
- <TableLoading isLoading={!showLoadingState && isLoading} className="table-loading">
378
- <TableLoadingInner>
379
- {loadingMessage}
380
- </TableLoadingInner>
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 {..._getTableProps(getTableBodyProps(getTableProps))} ref={tableRef}>
396
+ <TableCore
397
+ {..._getTableProps(getTableBodyProps(getTableProps))}
398
+ ref={tableRef}
399
+ >
385
400
  <THead className="table-head">
386
401
  {headerGroups.map((headerGroup) => (
387
- <TR {...headerGroup.getHeaderGroupProps(getTableElementProps(getHeaderGroupProps))}>
402
+ <TR
403
+ {...headerGroup.getHeaderGroupProps(
404
+ getTableElementProps(getHeaderGroupProps),
405
+ )}
406
+ >
388
407
  {headerGroup.headers.map((column) => {
389
- const headerProps = extendSortByProps(column) as DefaultObject;
408
+ const headerProps = extendSortByProps(
409
+ column,
410
+ ) as DefaultObject;
390
411
 
391
412
  return (
392
413
  <TH
393
- {...column.getHeaderProps(getTableElementInternalProps(
394
- headerProps, getHeaderProps, mainCellGetter,
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 {...group.getFooterGroupProps(getTableElementProps(getFooterGroupProps))}>
432
+ <TR
433
+ {...group.getFooterGroupProps(
434
+ getTableElementProps(getFooterGroupProps),
435
+ )}
436
+ >
408
437
  {group.headers.map((column) => (
409
- <TD {...column.getFooterProps(getTableElementProps(getFooterProps, mainCellGetter))}>
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
- <TRGroup key={`group_${row.index}`}>
425
- <TR {...row.getRowProps(getTableRowProps(getRowProps))}>
426
- <TD
427
- colSpan={visibleColumns.length}
428
- {...row.cells[0].getCellProps(getTableCellProps(getCellProps, cellGetter))}
429
- >
430
- <strong>{row.cells[0].render('Cell')}</strong>
431
- </TD>
432
- </TR>
433
- </TRGroup>
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
- <TRGroup key={`group_${row.index}`}>
439
- <TR {...row.getRowProps(getTableRowProps(getRowProps))}>
440
- {row.cells.map((cell: StandardCell) => (
441
- <TD {...cell.getCellProps(getTableCellProps(getCellProps, cellGetter))}>
442
- {cell.render('Cell')}
443
- </TD>
444
- ))}
445
- </TR>
446
- </TRGroup>
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 {...group.getFooterGroupProps(getTableElementProps(getFooterGroupProps))}>
498
+ <TR
499
+ {...group.getFooterGroupProps(
500
+ getTableElementProps(getFooterGroupProps),
501
+ )}
502
+ >
454
503
  {group.headers.map((column) => (
455
- <TD {...column.getFooterProps(getTableElementProps(getFooterProps, mainCellGetter))}>
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
 
@@ -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(({maxWidth, width, Header}: Column, key: number) => {
13
+ .map(({
14
+ maxWidth, width, Header, accessor,
15
+ }: Column) => {
14
16
  const column: Column<DefaultObject> = {
15
17
  Cell: () => <LoadingCellComponent />,
16
- accessor: `empty_${key}`,
18
+ accessor: accessor as string,
17
19
  };
18
20
  if (maxWidth) {
19
21
  column.maxWidth = maxWidth;