Merge pull request #3835 from KDSBrowne/accessibility-05-update

[HTML5] - Accessibility update 05
This commit is contained in:
Anton Georgiev 2017-04-24 15:34:05 -04:00 committed by GitHub
commit 835acfa195
6 changed files with 60 additions and 21 deletions

View File

@ -40,7 +40,7 @@ class Chat extends Component {
} = this.props; } = this.props;
return ( return (
<section className={styles.chat}> <div className={styles.chat}>
<header className={styles.header}> <header className={styles.header}>
<div className={styles.title}> <div className={styles.title}>
@ -83,7 +83,7 @@ class Chat extends Component {
chatName={chatName} chatName={chatName}
handleSendMessage={actions.handleSendMessage} handleSendMessage={actions.handleSendMessage}
/> />
</section> </div>
); );
} }
} }

View File

@ -15,6 +15,10 @@ const intlMessages = defineMessages({
id: 'app.chat.moreMessages', id: 'app.chat.moreMessages',
description: 'Chat message when the user has unread messages below the scroll', description: 'Chat message when the user has unread messages below the scroll',
}, },
emptyLogLabel: {
id: 'app.chat.emptyLogLabel',
description: 'aria-label used when chat log is empty',
}
}); });
class MessageList extends Component { class MessageList extends Component {
@ -132,19 +136,20 @@ class MessageList extends Component {
} }
render() { render() {
const { messages } = this.props; const { messages, intl } = this.props;
return ( return (
<div className={styles.messageListWrapper}> <div className={styles.messageListWrapper}>
<div <div
tabIndex="0"
role="log" role="log"
aria-atomic="false" tabIndex="0"
aria-live="polite"
aria-relevant="additions"
ref="scrollArea" ref="scrollArea"
className={styles.messageList}
id={this.props.id} id={this.props.id}
className={styles.messageList}
aria-live="polite"
aria-atomic="false"
aria-relevant="additions"
aria-label={intl.formatMessage(intlMessages.emptyLogLabel)}
> >
{messages.map((message) => ( {messages.map((message) => (
<MessageListItem <MessageListItem

View File

@ -17,6 +17,10 @@
} }
} }
.title {
color: $color-gray;
font-weight: 600;
}
.separator { .separator {
display: flex; display: flex;

View File

@ -0,0 +1,22 @@
import React, { Component, PropTypes } from 'react';
import styles from '../styles';
const propTypes = {
description: PropTypes.string,
};
export default class DropdownListTitle extends Component {
render() {
const { intl, description } = this.props;
return (
<div>
<li className={styles.title} aria-describedby="labelContext">{this.props.children}</li>
<div id="labelContext" aria-label={description}></div>
</div>
);
}
}
DropdownListTitle.propTypes = propTypes;

View File

@ -15,7 +15,8 @@ import DropdownContent from '/imports/ui/components/dropdown/content/component';
import DropdownList from '/imports/ui/components/dropdown/list/component'; import DropdownList from '/imports/ui/components/dropdown/list/component';
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component'; import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component'; import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
import DropdownListTitle from '/imports/ui/components/dropdown/list/title/component';
const propTypes = { const propTypes = {
user: React.PropTypes.shape({ user: React.PropTypes.shape({
name: React.PropTypes.string.isRequired, name: React.PropTypes.string.isRequired,
@ -45,6 +46,10 @@ const messages = defineMessages({
id: 'app.userlist.you', id: 'app.userlist.you',
description: 'Text for identifying your user', description: 'Text for identifying your user',
}, },
menuTitleContext: {
id: 'app.userlist.menuTitleContext',
description: 'adds context to userListItem menu title',
}
}); });
const userActionsTransition = { const userActionsTransition = {
@ -163,7 +168,7 @@ class UserListItem extends Component {
if (!isDropdownVisible) { if (!isDropdownVisible) {
const offsetPageTop = const offsetPageTop =
(dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight - scrollContainer.scrollTop); (dropdownTrigger.offsetTop + dropdownTrigger.offsetHeight - scrollContainer.scrollTop);
nextState.dropdownOffset = window.innerHeight - offsetPageTop; nextState.dropdownOffset = window.innerHeight - offsetPageTop;
nextState.dropdownDirection = 'bottom'; nextState.dropdownDirection = 'bottom';
} }
@ -174,7 +179,7 @@ class UserListItem extends Component {
/** /**
* Check if the dropdown is visible and is opened by the user * Check if the dropdown is visible and is opened by the user
* *
* @return True if is visible and opened by the user. * @return True if is visible and opened by the user.
*/ */
isDropdownActivedByUser() { isDropdownActivedByUser() {
@ -184,8 +189,8 @@ class UserListItem extends Component {
/** /**
* Return true if the content fit on the screen, false otherwise. * Return true if the content fit on the screen, false otherwise.
* *
* @param {number} contentOffSetTop * @param {number} contentOffSetTop
* @param {number} contentOffsetHeight * @param {number} contentOffsetHeight
* @return True if the content fit on the screen, false otherwise. * @return True if the content fit on the screen, false otherwise.
*/ */
@ -230,7 +235,9 @@ class UserListItem extends Component {
return ( return (
<li <li
role="button" role="button"
aria-haspopup="true" aria-haspopup="true"
aria-live="assertive"
aria-relevant="additions"
className={cx(styles.userListItem, userItemContentsStyle)}> className={cx(styles.userListItem, userItemContentsStyle)}>
{this.renderUserContents()} {this.renderUserContents()}
</li> </li>
@ -240,6 +247,7 @@ class UserListItem extends Component {
renderUserContents() { renderUserContents() {
const { const {
user, user,
intl,
} = this.props; } = this.props;
let actions = this.getAvailableActions(); let actions = this.getAvailableActions();
@ -277,13 +285,11 @@ class UserListItem extends Component {
<DropdownList> <DropdownList>
{ {
[ [
(<DropdownListItem (<DropdownListTitle
className={styles.actionsHeader} description={intl.formatMessage(messages.menuTitleContext)}>
key={_.uniqueId('action-header')} {user.name}
label={user.name} </DropdownListTitle>),
style={{ fontWeight: 600 }}
defaultMessage={user.name} />),
(<DropdownListSeparator key={_.uniqueId('action-separator')} />), (<DropdownListSeparator key={_.uniqueId('action-separator')} />),
].concat(actions) ].concat(actions)
} }

View File

@ -15,9 +15,11 @@
"app.chat.closeChatLabel": "Close {title}", "app.chat.closeChatLabel": "Close {title}",
"app.chat.hideChatLabel": "Hide {title}", "app.chat.hideChatLabel": "Hide {title}",
"app.chat.moreMessages": "More messages below", "app.chat.moreMessages": "More messages below",
"app.userlist.menuTitleContext": "available options",
"app.userlist.chatlistitem.unreadSingular": "{count} New Message", "app.userlist.chatlistitem.unreadSingular": "{count} New Message",
"app.userlist.chatlistitem.unreadPlural": "{count} New Messages", "app.userlist.chatlistitem.unreadPlural": "{count} New Messages",
"app.chat.Label": "Chat", "app.chat.Label": "Chat",
"app.chat.emptyLogLabel": "Chat log empty",
"app.media.Label": "Media", "app.media.Label": "Media",
"app.presentation.presentationToolbar.prevSlideLabel": "Previous slide", "app.presentation.presentationToolbar.prevSlideLabel": "Previous slide",
"app.presentation.presentationToolbar.prevSlideDescrip": "Change the presentation to the previous slide", "app.presentation.presentationToolbar.prevSlideDescrip": "Change the presentation to the previous slide",