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:
parent
d9daed0a4f
commit
2443b857f6
|
@ -1,6 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Revert Card component removal #7167.
|
||||
- Add rowKey prop to Table and TableCard component. #7196
|
||||
|
||||
# 7.0.0
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue