Add rowKey prop to table for allowing custom keys in rows (https://github.com/woocommerce/woocommerce-admin/pull/7196)

* Add rowKey prop to table for allowing custom keys in rows

* Add changelog

* Add test

* Fix lint errors
This commit is contained in:
louwie17 2021-06-18 09:18:19 -03:00 committed by GitHub
parent d9daed0a4f
commit 2443b857f6
6 changed files with 58 additions and 4 deletions

View File

@ -1,6 +1,7 @@
# Unreleased
- Revert Card component removal #7167.
- Add rowKey prop to Table and TableCard component. #7196
# 7.0.0

View File

@ -76,6 +76,7 @@ Name | Type | Default | Description
`title` | String | `null` | (required) The title used in the card header, also used as the caption for the content in this table
`totalRows` | Number | `null` | (required) The total number of rows (across all pages)
`baseSearchQuery` | Object | `{}` | Pass in query parameters to be included in the path when onSearch creates a new url
`rowKey` | Function(row, index): string | `null` | Function used for the row key.
### `labels` structure
@ -213,6 +214,7 @@ const rows = [
caption="Revenue Last Week"
rows={ rows }
headers={ headers }
rowKey={ row => row.display }
/>
```
@ -228,6 +230,7 @@ Name | Type | Default | Description
`query` | Object | `{}` | The query string represented in object form
`rows` | Array | `null` | (required) An array of arrays of display/value object pairs
`rowHeader` | One of type: number, bool | `0` | Which column should be the row header, defaults to the first item (`0`) (but could be set to `1`, if the first col is checkboxes, for example). Set to false to disable row headers
`rowKey` | Function(row, index): string | `null` | Function used to get the row key.
### `headers` structure

View File

@ -152,6 +152,7 @@ class TableCard extends Component {
summary,
title,
totalRows,
rowKey,
} = this.props;
const { showCols } = this.state;
const allHeaders = this.props.headers;
@ -238,6 +239,7 @@ class TableCard extends Component {
caption={ title }
query={ query }
onSort={ onSort || onQueryChange( 'sort' ) }
rowKey={ rowKey }
/>
) }
</CardBody>
@ -350,6 +352,11 @@ TableCard.propTypes = {
* The total number of rows (across all pages).
*/
totalRows: PropTypes.number.isRequired,
/**
* The rowKey used for the key value on each row, this can be a string of the key or a function that returns the value.
* This uses the index if not defined.
*/
rowKey: PropTypes.func,
};
TableCard.defaultProps = {

View File

@ -11,7 +11,12 @@ import { rows, headers } from './index';
export const Basic = () => (
<Card size={ null }>
<Table caption="Revenue Last Week" rows={ rows } headers={ headers } />
<Table
caption="Revenue Last Week"
rows={ rows }
headers={ headers }
rowKey={ ( row ) => row[ 0 ].value }
/>
</Card>
);

View File

@ -60,6 +60,7 @@ class Table extends Component {
this.container = createRef();
this.sortBy = this.sortBy.bind( this );
this.updateTableShadow = this.updateTableShadow.bind( this );
this.getRowKey = this.getRowKey.bind( this );
}
componentDidMount() {
@ -123,6 +124,13 @@ class Table extends Component {
}
}
getRowKey( row, index ) {
if ( this.props.rowKey && typeof this.props.rowKey === 'function' ) {
return this.props.rowKey( row, index );
}
return index;
}
render() {
const {
ariaHidden,
@ -245,7 +253,7 @@ class Table extends Component {
<th
role="columnheader"
scope="col"
key={ i }
key={ header.key || i }
{ ...thProps }
>
{ isSortable ? (
@ -286,7 +294,7 @@ class Table extends Component {
</tr>
{ hasData ? (
rows.map( ( row, i ) => (
<tr key={ i }>
<tr key={ this.getRowKey( row, i ) }>
{ row.map( ( cell, j ) => {
const {
cellClassName,
@ -306,12 +314,17 @@ class Table extends Component {
headers[ j ].key,
}
);
const cellKey =
this.getRowKey(
row,
i
).toString() + j;
return (
<Cell
scope={
isHeader ? 'row' : null
}
key={ j }
key={ cellKey }
className={ cellClasses }
>
{ getDisplay( cell ) }
@ -431,6 +444,11 @@ Table.propTypes = {
* is checkboxes, for example). Set to false to disable row headers.
*/
rowHeader: PropTypes.oneOfType( [ PropTypes.number, PropTypes.bool ] ),
/**
* The rowKey used for the key value on each row, a function that returns the key.
* Defaults to index.
*/
rowKey: PropTypes.func,
};
Table.defaultProps = {

View File

@ -74,4 +74,24 @@ describe( 'TableCard', () => {
// We shouldn't get here if an error occurred.
expect( true ).toBe( true );
} );
it( 'should render rows correctly with custom rowKey prop', () => {
render(
<TableCard
title="Revenue"
headers={ mockHeaders }
isLoading={ false }
rows={ mockData }
rowsPerPage={ 1 }
totalRows={ 5 }
rowKey={ ( row ) => row[ 1 ].value }
/>
);
for ( const row of mockData ) {
expect(
screen.queryByText( row[ 0 ].display )
).toBeInTheDocument();
}
} );
} );