Merge pull request woocommerce/woocommerce-admin#2801 from woocommerce/add/2613-empty-table-state

Add empty state to tables
This commit is contained in:
Jeff Stieler 2019-08-16 08:23:31 -07:00 committed by GitHub
commit 90edd4e5a6
6 changed files with 74 additions and 26 deletions

View File

@ -6,6 +6,8 @@
- Added a new `<SimpleSelectControl />` component.
- Added a new `<WebPreview />` component.
- SearchListItem component: fix long count values being cut-off in IE11.
- Add `disabled` prop to CompareButton, Search, and TableCard components.
- Table component: add empty table display.
# 3.1.0
- Added support for a `countLabel` prop on `SearchListItem` to allow custom counts.

View File

@ -12,8 +12,8 @@ import { Button, Tooltip } from '@wordpress/components';
*
* @return { object } -
*/
const CompareButton = ( { className, count, children, helpText, onClick } ) =>
count < 2 ? (
const CompareButton = ( { className, count, children, disabled, helpText, onClick } ) =>
! disabled && count < 2 ? (
<Tooltip text={ helpText }>
<span className={ className }>
<Button className="woocommerce-compare-button" isDefault disabled={ true }>
@ -26,6 +26,7 @@ const CompareButton = ( { className, count, children, helpText, onClick } ) =>
className={ classnames( 'woocommerce-compare-button', className ) }
isDefault
onClick={ onClick }
disabled={ disabled }
>
{ children }
</Button>
@ -52,6 +53,10 @@ CompareButton.propTypes = {
* The function called when the button is clicked.
*/
onClick: PropTypes.func.isRequired,
/**
* Whether the control is disabled or not.
*/
disabled: PropTypes.bool,
};
export default CompareButton;

View File

@ -178,6 +178,7 @@ class Search extends Component {
selected,
showClearButton,
staticResults,
disabled,
} = this.props;
const { value = '', isActive } = this.state;
const aria = {
@ -239,6 +240,7 @@ class Search extends Component {
shouldRenderTags ? `search-inline-input-${ instanceId }` : null
}
{ ...aria }
disabled={ disabled }
/>
<span id={ `search-inline-input-${ instanceId }` } className="screen-reader-text">
{ __( 'Move backward for selected items', 'woocommerce-admin' ) }
@ -257,6 +259,7 @@ class Search extends Component {
aria-owns={ listBoxId }
aria-activedescendant={ activeId }
{ ...aria }
disabled={ disabled }
/>
</Fragment>
)
@ -338,6 +341,10 @@ Search.propTypes = {
* Render results list positioned statically instead of absolutely.
*/
staticResults: PropTypes.bool,
/**
* Whether the control is disabled or not.
*/
disabled: PropTypes.bool,
};
Search.defaultProps = {
@ -347,6 +354,7 @@ Search.defaultProps = {
inlineTags: false,
showClearButton: false,
staticResults: false,
disabled: false,
};
export default withInstanceId( Search );

View File

@ -250,7 +250,8 @@ class TableCard extends Component {
getAllCheckbox() {
const { ids = [] } = this.props;
const { selectedRows } = this.state;
const isAllChecked = ids.length > 0 && ids.length === selectedRows.length;
const hasData = ids.length > 0;
const isAllChecked = hasData && ids.length === selectedRows.length;
return {
cellClassName: 'is-checkbox-column',
label: (
@ -259,6 +260,7 @@ class TableCard extends Component {
onChange={ this.selectAllRows }
aria-label={ __( 'Select All' ) }
checked={ isAllChecked }
disabled={ ! hasData }
/>
),
required: true,
@ -295,6 +297,7 @@ class TableCard extends Component {
} );
headers = [ this.getAllCheckbox(), ...headers ];
}
const hasData = 0 < totalRows;
const className = classnames( 'woocommerce-analytics__card', {
'woocommerce-table': true,
@ -316,6 +319,7 @@ class TableCard extends Component {
labels.helpText || __( 'Check at least two items below to compare', 'woocommerce-admin' )
}
onClick={ this.onCompare }
disabled={ ! hasData }
>
{ labels.compareButton || __( 'Compare', 'woocommerce-admin' ) }
</CompareButton>
@ -330,13 +334,14 @@ class TableCard extends Component {
selected={ searchedLabels }
showClearButton={ true }
type={ searchBy }
disabled={ ! hasData }
/>
),
( downloadable || onClickDownload ) && (
<IconButton
key="download"
className="woocommerce-table__download-button"
disabled={ isLoading }
disabled={ isLoading || ! hasData }
onClick={ this.onClickDownload }
isLink
>

View File

@ -186,10 +186,15 @@
}
.woocommerce-table__header,
.woocommerce-table__item {
@include font-size( 13 );
.woocommerce-table__item,
.woocommerce-table__empty-item {
padding: $gap $gap-large;
border-bottom: 1px solid $core-grey-light-500;
}
.woocommerce-table__header,
.woocommerce-table__item {
@include font-size( 13 );
text-align: left;
> a:only-child {
@ -243,6 +248,17 @@
}
}
.woocommerce-table__empty-item {
text-align: center;
@include font-size( 18 );
color: $core-grey-dark-300;
font-weight: bold;
@include breakpoint( '<782px' ) {
@include font-size( 13 );
}
}
th.woocommerce-table__item {
font-weight: normal;
}

View File

@ -117,6 +117,7 @@ class Table extends Component {
} );
const sortedBy = query.orderby || get( find( headers, { defaultSort: true } ), 'key', false );
const sortDir = query.order || get( find( headers, { key: sortedBy } ), 'defaultOrder', DESC );
const hasData = !! rows.length;
return (
<div
@ -183,7 +184,7 @@ class Table extends Component {
)
}
aria-describedby={ labelId }
onClick={ this.sortBy( key ) }
onClick={ hasData ? this.sortBy( key ) : noop }
isDefault
>
{ textLabel }
@ -199,25 +200,36 @@ class Table extends Component {
);
} ) }
</tr>
{ rows.map( ( row, i ) => (
<tr key={ i }>
{ row.map( ( cell, j ) => {
const { cellClassName, isLeftAligned, isNumeric } = headers[ j ];
const isHeader = rowHeader === j;
const Cell = isHeader ? 'th' : 'td';
const cellClasses = classnames( 'woocommerce-table__item', cellClassName, {
'is-left-aligned': isLeftAligned,
'is-numeric': isNumeric,
'is-sorted': sortedBy === headers[ j ].key,
} );
return (
<Cell scope={ isHeader ? 'row' : null } key={ j } className={ cellClasses }>
{ getDisplay( cell ) }
</Cell>
);
} ) }
</tr>
) ) }
{ hasData
? (
rows.map( ( row, i ) => (
<tr key={ i }>
{ row.map( ( cell, j ) => {
const { cellClassName, isLeftAligned, isNumeric } = headers[ j ];
const isHeader = rowHeader === j;
const Cell = isHeader ? 'th' : 'td';
const cellClasses = classnames( 'woocommerce-table__item', cellClassName, {
'is-left-aligned': isLeftAligned,
'is-numeric': isNumeric,
'is-sorted': sortedBy === headers[ j ].key,
} );
return (
<Cell scope={ isHeader ? 'row' : null } key={ j } className={ cellClasses }>
{ getDisplay( cell ) }
</Cell>
);
} ) }
</tr>
) )
)
: (
<tr>
<td className="woocommerce-table__empty-item" colSpan={ headers.length }>
{ __( 'No data for the selected date range', 'woocommerce-admin' ) }
</td>
</tr>
)
}
</tbody>
</table>
</div>