Skip to content

Commit

Permalink
Merge pull request #1609 from carbon-design-system/table-hierarchy
Browse files Browse the repository at this point in the history
feat(table): enable single nested hierarchy styling
  • Loading branch information
tay1orjones authored Sep 19, 2020
2 parents 5ecac97 + 1b22d2b commit abefcbd
Show file tree
Hide file tree
Showing 9 changed files with 6,402 additions and 1,464 deletions.
8 changes: 7 additions & 1 deletion src/components/Table/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ const propTypes = {
hasPagination: PropTypes.bool,
hasRowSelection: PropTypes.oneOf(['multi', 'single', false]),
hasRowExpansion: PropTypes.bool,
hasRowNesting: PropTypes.bool,
hasRowNesting: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.shape({
/** If the hierarchy only has 1 nested level of children */
hasSingleNestedHierarchy: PropTypes.bool,
}),
]),
hasRowActions: PropTypes.bool,
hasFilter: PropTypes.oneOfType([
PropTypes.bool,
Expand Down
86 changes: 83 additions & 3 deletions src/components/Table/Table.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1762,13 +1762,93 @@ storiesOf('Watson IoT/Table', module)
<br />
You must also set hasRowExpansion to true in your table options
You must also set hasRowExpansion and hasRowNesting to true in your table options
<br />
~~~js
options={
hasRowExpansion: true
hasRowExpansion: true,
hasRowNesting: true
}
~~~
<br />
`,
propTables: [Table],
propTablesExclude: [StatefulTable],
},
}
)
.add(
'Stateful Example with single nested hierarchy',
() => {
const tableData = initialState.data.map((i, idx) => ({
...i,
children: [getNewRow(idx, 'A', true), getNewRow(idx, 'B', true)],
}));
return (
<div>
<StatefulTable
id="table"
{...initialState}
secondaryTitle={text('Secondary Title', `Row count: ${initialState.data.length}`)}
columns={tableColumns}
data={tableData}
options={{
...initialState.options,
hasRowNesting: {
hasSingleNestedHierarchy: true,
},
wrapCellText: select('wrapCellText', selectTextWrapping, 'always'),
}}
actions={actions}
lightweight={boolean('lightweight', false)}
/>
</div>
);
},
{
info: {
text: `
This stateful table has nested rows. To setup your table this way you must pass a children prop along with each of your data rows.
In addition, if there is a single level of row nesting, hasRowNesting can be customized to add additional styling seen in this story
<br />
~~~js
data=[
{
id: 'rowid',
values: {
col1: 'value1
},
children: [
{
id: 'child-rowid,
values: {
col1: 'nested-value1'
}
}
]
}
]
~~~
<br />
You must also set hasRowExpansion to true and hasRowNesting to an object with hasSingleLevelRowNesting to true in your table options
<br />
~~~js
options={
hasRowExpansion: true,
hasRowNesting: {
hasSingleLevelRowNesting: true
}
}
~~~
Expand Down Expand Up @@ -2203,7 +2283,7 @@ storiesOf('Watson IoT/Table', module)
}))}
options={{
hasPagination: true,
hasRowSelection: 'single',
hasRowSelection: 'multi',
hasRowExpansion: true,
hasRowNesting: true,
}}
Expand Down
8 changes: 7 additions & 1 deletion src/components/Table/TableBody/TableBody.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ const propTypes = {
totalColumns: PropTypes.number,
hasRowSelection: PropTypes.oneOf(['multi', 'single', false]),
hasRowExpansion: PropTypes.bool,
hasRowNesting: PropTypes.bool,
hasRowNesting: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.shape({
/** If the hierarchy only has 1 nested level of children */
hasSingleNestedHierarchy: PropTypes.bool,
}),
]),
hasRowActions: PropTypes.bool,
wrapCellText: PropTypes.oneOf(['always', 'never', 'auto']).isRequired,
truncateCellText: PropTypes.bool.isRequired,
Expand Down
30 changes: 20 additions & 10 deletions src/components/Table/TableBody/TableBodyRow/TableBodyRow.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { DataTable, Checkbox } from 'carbon-components-react';
import styled from 'styled-components';
Expand Down Expand Up @@ -49,7 +49,13 @@ const propTypes = {
options: PropTypes.shape({
hasRowSelection: PropTypes.oneOf(['multi', 'single', false]),
hasRowExpansion: PropTypes.bool,
hasRowNesting: PropTypes.bool,
hasRowNesting: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.shape({
/** If the hierarchy only has 1 nested level of children */
hasSingleNestedHierarchy: PropTypes.bool,
}),
]),
shouldExpandOnRowClick: PropTypes.bool,
wrapCellText: PropTypes.oneOf(['always', 'never', 'auto']).isRequired,
truncateCellText: PropTypes.bool.isRequired,
Expand Down Expand Up @@ -374,10 +380,13 @@ const TableBodyRow = ({
}) => {
const isEditMode = rowEditMode || singleRowEditMode;
const singleSelectionIndicatorWidth = hasRowSelection === 'single' ? 0 : 5;
const nestingOffset =
hasRowSelection === 'single'
? nestingLevel * 16 - singleSelectionIndicatorWidth
: nestingLevel * 16;
// if this a single hierarchy (i.e. only 1 level of nested children), do NOT show the gray offset
const nestingOffset = hasRowNesting?.hasSingleNestedHierarchy
? 0
: hasRowSelection === 'single'
? nestingLevel * 16 - singleSelectionIndicatorWidth
: nestingLevel * 16;

const rowSelectionCell =
hasRowSelection === 'multi' ? (
<TableCell
Expand All @@ -404,13 +413,14 @@ const TableBodyRow = ({

const firstVisibleColIndex = ordering.findIndex(col => !col.isHidden);
const tableCells = (
<React.Fragment>
<>
{rowSelectionCell}
{ordering.map((col, idx) => {
const matchingColumnMeta = columns && columns.find(column => column.id === col.columnId);
// initialColumnWidth for the table body cells is needed for tables that have fixed column widths
// and table-layout:auto combination so that cell content can be truncated
const initialColumnWidth = matchingColumnMeta && matchingColumnMeta.width;
// if this a single hierarchy (i.e. only 1 level of nested children), do NOT show the gray offset
const offset = firstVisibleColIndex === idx ? nestingOffset : 0;
const align =
matchingColumnMeta && matchingColumnMeta.align ? matchingColumnMeta.align : 'start';
Expand Down Expand Up @@ -476,11 +486,11 @@ const TableBodyRow = ({
) : (
undefined
)}
</React.Fragment>
</>
);
return hasRowExpansion || hasRowNesting ? (
isExpanded ? (
<React.Fragment key={id}>
<Fragment key={id}>
<StyledTableExpandRowExpanded
ariaLabel={clickToCollapseAria}
expandIconDescription={clickToCollapseAria}
Expand Down Expand Up @@ -509,7 +519,7 @@ const TableBodyRow = ({
<TableCell colSpan={totalColumns}>{rowDetails}</TableCell>
</StyledExpansionTableRow>
)}
</React.Fragment>
</Fragment>
) : (
<StyledTableExpandRow
key={id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ exports[`Storybook Snapshot tests and console checks Storyshots Watson IoT/Table
aria-disabled={false}
aria-expanded={false}
aria-haspopup="listbox"
aria-labelledby="downshift-19-label downshift-19-toggle-button"
aria-labelledby="downshift-20-label downshift-20-toggle-button"
className="bx--list-box__field"
disabled={false}
id="downshift-19-toggle-button"
id="downshift-20-toggle-button"
onClick={[Function]}
onKeyDown={[Function]}
type="button"
Expand Down Expand Up @@ -108,9 +108,9 @@ exports[`Storybook Snapshot tests and console checks Storyshots Watson IoT/Table
</div>
</button>
<div
aria-labelledby="downshift-19-label"
aria-labelledby="downshift-20-label"
className="bx--list-box__menu"
id="downshift-19-menu"
id="downshift-20-menu"
onBlur={[Function]}
onKeyDown={[Function]}
onMouseLeave={[Function]}
Expand Down
Loading

0 comments on commit abefcbd

Please sign in to comment.