Skip to content

Commit

Permalink
feat(Table): support custom components in expandable rows
Browse files Browse the repository at this point in the history
by using expandable cellFormatter or ExpandableRowContent component

- exposed isRowExpanded function for extensions to use
  • Loading branch information
suomiy committed Mar 15, 2019
1 parent 8ba0357 commit 19b1924
Show file tree
Hide file tree
Showing 16 changed files with 869 additions and 77 deletions.
53 changes: 26 additions & 27 deletions packages/patternfly-4/react-table/src/components/Table/Body.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Body } from 'reactabular-table';
import PropTypes from 'prop-types';
import { TableContext } from './Table';
import { isRowExpanded } from './utils';

const propTypes = {
/** Additional classes for table body. */
Expand All @@ -18,6 +19,9 @@ const defaultProps = {
onRowClick: () => undefined
};

const getFirstUserColumnIndex = headerData =>
headerData[0] ? ['onCollapse', 'onSelect'].filter(callbackName => headerData[0].extraParams[callbackName]).length : 0;

class ContextBody extends React.Component {
onRow = (row, props) => {
const { onRowClick } = this.props;
Expand All @@ -32,36 +36,34 @@ class ContextBody extends React.Component {
};
};

parentsExpanded(parentId) {
const { rows } = this.props;
return rows[parentId].hasOwnProperty('parent')
? this.parentsExpanded(rows[parentId].parent)
: rows[parentId].isOpen;
}

mapCells = (row, rowKey) => {
const { headerData } = this.props;
let shiftKey = Boolean(headerData[0] && headerData[0].extraParams.onSelect);
shiftKey += Boolean(headerData[0] && headerData[0].extraParams.onCollapse);
// column indexes start after generated optional columns
let additionalColsIndexShift = getFirstUserColumnIndex(headerData);

return {
...(row &&
(row.cells || row).reduce(
(acc, curr, key) => {
const currShift = shiftKey;
if (curr.props && curr.props.colSpan) {
shiftKey += shiftKey + curr.props && curr.props.colSpan - 1;
(acc, cell, cellIndex) => {
const isCellObject = cell === Object(cell);

const mappedCell = {
[headerData[cellIndex + additionalColsIndexShift].property]: {
title: isCellObject ? cell.title : cell,
props: {
isVisible: true,
...(isCellObject ? cell.props : null)
}
}
};

// increment the shift index when a cell spans multiple columns
if (isCellObject && cell.props && cell.props.colSpan) {
additionalColsIndexShift += cell.props.colSpan - 1;
}
return {
...acc,
...{
[headerData[currShift + key].property]: {
title: curr.title || curr,
props: {
isVisible: true,
...curr.props
}
}
}
...mappedCell
};
},
{ id: row.id !== undefined ? row.id : rowKey }
Expand All @@ -76,12 +78,9 @@ class ContextBody extends React.Component {
rows.map((oneRow, oneRowKey) => ({
...oneRow,
...this.mapCells(oneRow, oneRowKey),
...(oneRow.parent !== undefined
? {
isExpanded: this.parentsExpanded(oneRow.parent) && rows[oneRow.parent].isOpen
}
: {})
isExpanded: isRowExpanded(oneRow, rows)
}));
console.log(mappedRows);
return (
<React.Fragment>
{mappedRows && (
Expand Down
19 changes: 17 additions & 2 deletions packages/patternfly-4/react-table/src/components/Table/Table.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { FunctionComponent, HTMLProps, ReactNode, MouseEvent } from 'react';
import { SortByDirection } from './SortColumn';
import { DropdownPosition, DropdownDirection, OneOf, Omit } from '@patternfly/react-core';

interface OnSort {
(event: MouseEvent, columnIndex: number, extraData: IExtraColumnData): void
}

export const TableGridBreakpoint: {
grid: 'grid',
gridMd: 'grid-md',
Expand All @@ -15,16 +19,27 @@ export const TableVariant: {
export interface IRowData {
}

export interface IColumn {
extraParams: {
sortBy?: ISortBy;
onSort?: OnSort;
}
}

export interface IExtraColumnData {
columnIndex: number,
column: Object,
column: IColumn,
property: string,
}

export interface IExtraData extends IExtraColumnData {
rowIndex: number
}

export interface IExtra extends IExtraData {
rowData: IRowData,
}

export interface ISortBy {
index?: Number;
direction?: OneOf<typeof SortByDirection, keyof typeof SortByDirection>;
Expand Down Expand Up @@ -68,7 +83,7 @@ export interface TableProps extends Omit<Omit<HTMLProps<HTMLTableElement>, 'onSe
sortBy?: ISortBy;
onCollapse?: (event: MouseEvent, rowIndex: number,isOpen: boolean, rowData: IRowData, extraData: IExtraData) => void;
onSelect?: (event: MouseEvent, isSelected: boolean, rowIndex: number, rowData: IRowData, extraData: IExtraData) => void;
onSort?: (event: MouseEvent, columnIndex: number, extraData: IExtraColumnData) => void;
onSort?: OnSort;
actions?: Array<IAction | ISeparator>;
actionResolver?: (rowData: IRowData, extraData: IExtraData) => Array<IAction | ISeparator>;
areActionsDisabled?: (rowData: IRowData, extraData: IExtraData) => boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
TableVariant,
cellWidth,
headerCol,
sortable
sortable,
expandable
} from './index';
import { rows, columns, actions } from '../../test-helpers/data-sets';

Expand Down Expand Up @@ -130,6 +131,7 @@ test('Collapsible table', () => {
rows[1] = { ...rows[1], parent: 0 };
rows[3] = { ...rows[3], isOpen: false };
rows[4] = { ...rows[4], parent: 3 };
columns[0] = { ...columns[0], cellFormatters: [expandable] };
const onCollapse = () => undefined;
const view = mount(
<Table aria-label="Aria labeled" onCollapse={onCollapse} cells={columns} rows={rows}>
Expand Down
Loading

0 comments on commit 19b1924

Please sign in to comment.