* Add unread indicator to mobile panel toggle

* Add accessible unread indiciators

* Add default functions for the WP Notices component
This commit is contained in:
Justin Shreve 2018-07-18 11:20:00 -04:00 committed by GitHub
parent 22028283ef
commit 3239a74eef
4 changed files with 73 additions and 23 deletions

View File

@ -28,10 +28,12 @@ class ActivityPanel extends Component {
this.togglePanel = this.togglePanel.bind( this );
this.toggleMobile = this.toggleMobile.bind( this );
this.renderTab = this.renderTab.bind( this );
this.updateNoticeFlag = this.updateNoticeFlag.bind( this );
this.state = {
isPanelOpen: false,
mobileOpen: false,
currentTab: '',
hasWordPressNotices: false,
};
}
@ -80,6 +82,12 @@ class ActivityPanel extends Component {
}
}
updateNoticeFlag( noticeCount ) {
this.setState( {
hasWordPressNotices: noticeCount > 0,
} );
}
// TODO Pull in dynamic unread status/count
getTabs() {
return [
@ -99,13 +107,13 @@ class ActivityPanel extends Component {
name: 'stock',
title: __( 'Stock', 'wc-admin' ),
icon: <Gridicon icon="clipboard" />,
unread: true,
unread: false,
},
{
name: 'reviews',
title: __( 'Reviews', 'wc-admin' ),
icon: <Gridicon icon="star" />,
unread: true,
unread: false,
},
];
}
@ -181,20 +189,27 @@ class ActivityPanel extends Component {
onClick={ partial( this.togglePanel, tab.name ) }
icon={ tab.icon }
>
{ tab.title }
{ tab.title }{' '}
{ tab.unread && (
<span className="screen-reader-text">{ __( 'unread activity', 'wc-admin' ) }</span>
) }
</IconButton>
);
}
render() {
const tabs = this.getTabs();
const { currentTab, mobileOpen } = this.state;
const { currentTab, mobileOpen, hasWordPressNotices } = this.state;
const headerId = uniqueId( 'activity-panel-header_' );
const panelClasses = classnames( 'woocommerce-layout__activity-panel', {
'is-mobile-open': this.state.mobileOpen,
} );
// TODO Replace the mobile toggle with the Woo bubble Gridicon once it has been added.
const hasUnread = hasWordPressNotices || tabs.some( tab => tab.unread );
const viewLabel = hasUnread
? __( 'View Activity Panel, you have unread activity', 'wc-admin' )
: __( 'View Activity Panel', 'wc-admin' );
return (
<div>
<H id={ headerId } className="screen-reader-text">
@ -203,12 +218,14 @@ class ActivityPanel extends Component {
<Section component="aside" id="woocommerce-activity-panel" aria-labelledby={ headerId }>
<IconButton
onClick={ this.toggleMobile }
icon={ mobileOpen ? <Gridicon icon="cross-small" /> : <ActivityPanelToggleBubble /> }
label={
mobileOpen
? __( 'Close Activity Panel', 'wc-admin' )
: __( 'View Activity Panel', 'wc-admin' )
icon={
mobileOpen ? (
<Gridicon icon="cross-small" />
) : (
<ActivityPanelToggleBubble hasUnread={ hasUnread } />
)
}
label={ mobileOpen ? __( 'Close Activity Panel', 'wc-admin' ) : viewLabel }
aria-expanded={ mobileOpen }
tooltip={ false }
className="woocommerce-layout__activity-panel-mobile-toggle"
@ -223,6 +240,7 @@ class ActivityPanel extends Component {
<WordPressNotices
showNotices={ 'wpnotices' === currentTab }
togglePanel={ this.togglePanel }
onCountUpdate={ this.updateNoticeFlag }
/>
</NavigableMenu>
{ this.renderPanel() }

View File

@ -155,6 +155,20 @@
}
}
.woocommerce-layout__activity-panel-toggle-bubble.has-unread:after {
content: ' ';
position: absolute;
padding: 1px;
background: $core-orange;
border: 2px solid white;
width: 4px;
height: 4px;
display: inline-block;
border-radius: 50%;
top: 6px;
right: 4px;
}
@keyframes tabSwitch {
0%,
100% {

View File

@ -3,19 +3,21 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import PropTypes from 'prop-types';
const ActivityPanelToggleBubble = ( { height = 24, width = 24 } ) => {
const ActivityPanelToggleBubble = ( { height = 24, width = 24, hasUnread = false } ) => {
const classes = classnames( 'woocommerce-layout__activity-panel-toggle-bubble', {
'has-unread': hasUnread,
} );
/* eslint-disable max-len */
return (
<svg
className="woocommerce-layout__activity-panel-toggle-bubble"
height={ height }
width={ width }
viewBox="0 0 24 24"
>
<path d="M18.9 2H5.1C3.4 2 2 3.4 2 5.1v10.7C2 17.6 3.4 19 5.1 19H9l6 3-1-3h4.9c1.7 0 3.1-1.4 3.1-3.1V5.1C22 3.4 20.6 2 18.9 2zm-1.5 4.5c-.4.8-.8 2.1-1 3.9-.3 1.8-.4 3.1-.3 4.1 0 .3 0 .5-.1.7-.1.2-.3.4-.6.4s-.6-.1-.9-.4c-1-1-1.8-2.6-2.4-4.6-.7 1.4-1.2 2.4-1.6 3.1-.6 1.2-1.2 1.8-1.6 1.9-.3 0-.5-.2-.8-.7-.5-1.4-1.1-4.2-1.7-8.2 0-.3 0-.5.2-.7.1-.2.4-.3.7-.4.5 0 .9.2.9.8.3 2.3.7 4.2 1.1 5.7l2.4-4.5c.2-.4.4-.6.8-.6.5 0 .8.3.9.9.3 1.4.6 2.6 1 3.7.3-2.7.8-4.7 1.4-5.9.2-.3.4-.5.7-.5.2 0 .5.1.7.2.2.2.3.4.3.6 0 .2 0 .4-.1.5z" />
</svg>
<div className={ classes }>
<svg height={ height } width={ width } viewBox="0 0 24 24">
<path d="M18.9 2H5.1C3.4 2 2 3.4 2 5.1v10.7C2 17.6 3.4 19 5.1 19H9l6 3-1-3h4.9c1.7 0 3.1-1.4 3.1-3.1V5.1C22 3.4 20.6 2 18.9 2zm-1.5 4.5c-.4.8-.8 2.1-1 3.9-.3 1.8-.4 3.1-.3 4.1 0 .3 0 .5-.1.7-.1.2-.3.4-.6.4s-.6-.1-.9-.4c-1-1-1.8-2.6-2.4-4.6-.7 1.4-1.2 2.4-1.6 3.1-.6 1.2-1.2 1.8-1.6 1.9-.3 0-.5-.2-.8-.7-.5-1.4-1.1-4.2-1.7-8.2 0-.3 0-.5.2-.7.1-.2.4-.3.7-.4.5 0 .9.2.9.8.3 2.3.7 4.2 1.1 5.7l2.4-4.5c.2-.4.4-.6.8-.6.5 0 .8.3.9.9.3 1.4.6 2.6 1 3.7.3-2.7.8-4.7 1.4-5.9.2-.3.4-.5.7-.5.2 0 .5.1.7.2.2.2.3.4.3.6 0 .2 0 .4-.1.5z" />
</svg>
</div>
);
/* eslint-enable max-len */
};
@ -23,6 +25,7 @@ const ActivityPanelToggleBubble = ( { height = 24, width = 24 } ) => {
ActivityPanelToggleBubble.propTypes = {
height: PropTypes.number,
width: PropTypes.number,
hasUnread: PropTypes.bool,
};
export default ActivityPanelToggleBubble;

View File

@ -3,11 +3,12 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { IconButton } from '@wordpress/components';
import classnames from 'classnames';
import { Component } from '@wordpress/element';
import Gridicon from 'gridicons';
import { partial } from 'lodash';
import classnames from 'classnames';
import { IconButton } from '@wordpress/components';
import { partial, noop } from 'lodash';
import PropTypes from 'prop-types';
class WordPressNotices extends Component {
constructor() {
@ -92,6 +93,7 @@ class WordPressNotices extends Component {
count = count - 1; // Remove 1 for `wp-header-end` which is a child of wp__notice-list
this.props.onCountUpdate( count );
this.setState( { count, notices, noticesOpen, screenMeta, screenLinks } );
// Move collapsed WordPress notifications into the main wc-admin body
@ -139,6 +141,7 @@ class WordPressNotices extends Component {
updateCount() {
const updatedCount = this.state.count - 1;
this.setState( { count: updatedCount } );
this.props.onCountUpdate( updatedCount );
if ( updatedCount < 1 ) {
this.props.togglePanel( 'wpnotices' ); // Close the panel since all of the notices have been closed.
@ -196,10 +199,22 @@ class WordPressNotices extends Component {
role="tab"
tabIndex={ showNotices ? null : -1 }
>
{ __( 'Notices', 'wc-admin' ) }
{ __( 'Notices', 'wc-admin' ) }{' '}
<span className="screen-reader-text">{ __( 'unread activity', 'wc-admin' ) }</span>
</IconButton>
);
}
}
WordPressNotices.propTypes = {
showNotices: PropTypes.bool,
togglePanel: PropTypes.func,
onCountUpdate: PropTypes.func,
};
WordPressNotices.defaultProps = {
togglePanel: noop,
onCountUpdate: noop,
};
export default WordPressNotices;